summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCyborus <87248184+Cyborus04@users.noreply.github.com>2023-11-09 18:46:08 +0100
committerCyborus <87248184+Cyborus04@users.noreply.github.com>2023-11-09 18:46:08 +0100
commit90084b9d7ad336ff13cbaf4b69a4300fa09ace49 (patch)
tree2d563d57c0644fec7e0962862c3f68295325d612
parentMerge pull request 'praise rustfmt' (#10) from fmt into main (diff)
downloadforgejo-cli-90084b9d7ad336ff13cbaf4b69a4300fa09ace49.tar.xz
forgejo-cli-90084b9d7ad336ff13cbaf4b69a4300fa09ace49.zip
move forgejo-api to its own repo
-rw-r--r--Cargo.lock1
-rw-r--r--Cargo.toml4
-rw-r--r--forgejo-api/Cargo.toml15
-rw-r--r--forgejo-api/src/lib.rs223
4 files changed, 2 insertions, 241 deletions
diff --git a/Cargo.lock b/Cargo.lock
index cc8b9fd..44f6ea7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -307,6 +307,7 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "forgejo-api"
version = "0.1.0"
+source = "git+https://codeberg.org/Cyborus/forgejo-api.git#285fddb2ea3bbc9bfc1116e92167347194594d61"
dependencies = [
"reqwest",
"serde",
diff --git a/Cargo.toml b/Cargo.toml
index 291646c..45276b0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,7 +9,7 @@ edition = "2021"
clap = { version = "4.3.11", features = ["derive"] }
directories = "5.0.1"
eyre = "0.6.8"
-forgejo-api = { path = "./forgejo-api" }
+forgejo-api = { git = "https://codeberg.org/Cyborus/forgejo-api.git" }
futures = "0.3.28"
git2 = "0.17.2"
open = "5.0.0"
@@ -19,5 +19,3 @@ soft_assert = "0.1.1"
tokio = { version = "1.29.1", features = ["full"] }
url = "2.4.0"
-[workspace]
-members = ["forgejo-api"]
diff --git a/forgejo-api/Cargo.toml b/forgejo-api/Cargo.toml
deleted file mode 100644
index 14f45dd..0000000
--- a/forgejo-api/Cargo.toml
+++ /dev/null
@@ -1,15 +0,0 @@
-[package]
-name = "forgejo-api"
-version = "0.1.0"
-edition = "2021"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-reqwest = { version = "0.11.18", features = ["json"] }
-soft_assert = "0.1.1"
-thiserror = "1.0.43"
-tokio = { version = "1.29.1", features = ["net"] }
-url = { version = "2.4.0", features = ["serde"] }
-serde = { version = "1.0.168", features = ["derive"] }
-time = { version = "0.3.22", features = ["parsing", "serde"] }
diff --git a/forgejo-api/src/lib.rs b/forgejo-api/src/lib.rs
deleted file mode 100644
index d5bd6a0..0000000
--- a/forgejo-api/src/lib.rs
+++ /dev/null
@@ -1,223 +0,0 @@
-use reqwest::{Client, Request, StatusCode};
-use serde::{de::DeserializeOwned, Serialize};
-use soft_assert::*;
-use url::Url;
-
-pub struct Forgejo {
- url: Url,
- client: Client,
-}
-
-#[derive(thiserror::Error, Debug)]
-pub enum ForgejoError {
- #[error("url must have a host")]
- HostRequired,
- #[error("scheme must be http or https")]
- HttpRequired,
- #[error("{0}")] // for some reason, you can't use `source` and `transparent` together
- ReqwestError(#[source] reqwest::Error),
- #[error("API key should be ascii")]
- KeyNotAscii,
- #[error("the response from forgejo was not properly structured")]
- BadStructure,
- #[error("unexpected status code {} {}", .0.as_u16(), .0.canonical_reason().unwrap_or(""))]
- UnexpectedStatusCode(StatusCode),
- #[error("{} {}: {}", .0.as_u16(), .0.canonical_reason().unwrap_or(""), .1)]
- ApiError(StatusCode, String),
-}
-
-impl From<reqwest::Error> for ForgejoError {
- fn from(e: reqwest::Error) -> Self {
- if e.is_decode() {
- ForgejoError::BadStructure
- } else {
- ForgejoError::ReqwestError(e)
- }
- }
-}
-
-impl Forgejo {
- pub fn new(api_key: &str, url: Url) -> Result<Self, ForgejoError> {
- Self::with_user_agent(api_key, url, "forgejo-api-rs")
- }
-
- pub fn with_user_agent(
- api_key: &str,
- url: Url,
- user_agent: &str,
- ) -> Result<Self, ForgejoError> {
- soft_assert!(
- matches!(url.scheme(), "http" | "https"),
- Err(ForgejoError::HttpRequired)
- );
-
- let mut headers = reqwest::header::HeaderMap::new();
- let mut key_header: reqwest::header::HeaderValue = format!("token {api_key}")
- .try_into()
- .map_err(|_| ForgejoError::KeyNotAscii)?;
- // key_header.set_sensitive(true);
- headers.insert("Authorization", key_header);
- let client = Client::builder()
- .user_agent(user_agent)
- .default_headers(headers)
- .build()?;
- dbg!(&client);
- Ok(Self { url, client })
- }
-
- pub async fn get_repo(&self, user: &str, repo: &str) -> Result<Option<Repo>, ForgejoError> {
- self.get_opt(&format!("repos/{user}/{repo}/")).await
- }
-
- pub async fn create_repo(&self, repo: CreateRepoOption) -> Result<Repo, ForgejoError> {
- self.post("user/repos", &repo).await
- }
-
- /// Returns user info about the authorized user.
- pub async fn myself(&self) -> Result<User, ForgejoError> {
- self.get("user").await
- }
-
- pub async fn get_user(&self, user: &str) -> Result<Option<User>, ForgejoError> {
- self.get_opt(&format!("users/{user}/")).await
- }
-
- pub async fn get_followers(&self, user: &str) -> Result<Option<Vec<User>>, ForgejoError> {
- self.get_opt(&format!("users/{user}/followers/")).await
- }
-
- pub async fn get_following(&self, user: &str) -> Result<Option<Vec<User>>, ForgejoError> {
- self.get_opt(&format!("users/{user}/following/")).await
- }
-
- async fn get<T: DeserializeOwned>(&self, path: &str) -> Result<T, ForgejoError> {
- let url = self.url.join("api/v1/").unwrap().join(path).unwrap();
- let request = self.client.get(url).build()?;
- self.execute(request).await
- }
-
- async fn get_opt<T: DeserializeOwned>(&self, path: &str) -> Result<Option<T>, ForgejoError> {
- let url = self.url.join("api/v1/").unwrap().join(path).unwrap();
- let request = self.client.get(url).build()?;
- self.execute_opt(request).await
- }
-
- async fn post<T: Serialize, U: DeserializeOwned>(
- &self,
- path: &str,
- body: &T,
- ) -> Result<U, ForgejoError> {
- let url = self.url.join("api/v1/").unwrap().join(path).unwrap();
- let request = self.client.post(url).json(body).build()?;
- self.execute(request).await
- }
-
- async fn execute<T: DeserializeOwned>(&self, request: Request) -> Result<T, ForgejoError> {
- let response = self.client.execute(dbg!(request)).await?;
- match response.status() {
- status if status.is_success() => Ok(response.json::<T>().await?),
- status if status.is_client_error() => Err(ForgejoError::ApiError(
- status,
- response.json::<ErrorMessage>().await?.message,
- )),
- status => Err(ForgejoError::UnexpectedStatusCode(status)),
- }
- }
-
- /// Like `execute`, but returns `Ok(None)` on 404.
- async fn execute_opt<T: DeserializeOwned>(
- &self,
- request: Request,
- ) -> Result<Option<T>, ForgejoError> {
- let response = self.client.execute(dbg!(request)).await?;
- match response.status() {
- status if status.is_success() => Ok(Some(response.json::<T>().await?)),
- StatusCode::NOT_FOUND => Ok(None),
- status if status.is_client_error() => Err(ForgejoError::ApiError(
- status,
- response.json::<ErrorMessage>().await?.message,
- )),
- status => Err(ForgejoError::UnexpectedStatusCode(status)),
- }
- }
-}
-
-#[derive(serde::Deserialize)]
-struct ErrorMessage {
- message: String,
- // intentionally ignored, no need for now
- // url: Url
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct Repo {
- pub clone_url: Url,
- #[serde(with = "time::serde::rfc3339")]
- pub created_at: time::OffsetDateTime,
- pub default_branch: String,
- pub description: String,
- pub fork: bool,
- pub forks_count: u64,
- pub full_name: String,
-
- pub owner: User,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct User {
- pub active: bool,
- pub avatar_url: Url,
- #[serde(with = "time::serde::rfc3339")]
- pub created: time::OffsetDateTime,
- pub description: String,
- pub email: String,
- pub followers_count: u64,
- pub following_count: u64,
- pub full_name: String,
- pub id: u64,
- pub is_admin: bool,
- pub language: String,
- #[serde(with = "time::serde::rfc3339")]
- pub last_login: time::OffsetDateTime,
- pub location: String,
- pub login: String,
- pub login_name: String,
- pub prohibit_login: bool,
- pub restricted: bool,
- pub starred_repos_count: u64,
- pub website: String,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub enum UserVisibility {
- #[serde(rename = "public")]
- Public,
- #[serde(rename = "limited")]
- Limited,
- #[serde(rename = "private")]
- Private,
-}
-
-#[derive(serde::Serialize, Debug, PartialEq)]
-pub struct CreateRepoOption {
- pub auto_init: bool,
- pub default_branch: String,
- pub description: Option<String>,
- pub gitignores: String,
- pub issue_labels: String,
- pub license: String,
- pub name: String,
- pub private: bool,
- pub readme: String,
- pub template: bool,
- pub trust_model: TrustModel,
-}
-
-#[derive(serde::Serialize, Debug, PartialEq)]
-pub enum TrustModel {
- Default,
- Collaborator,
- Committer,
- #[serde(rename = "collaboratorcommiter")]
- CollaboratorCommitter,
-}