diff options
| author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2025-09-06 10:31:40 +0200 |
|---|---|---|
| committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2025-09-06 10:31:40 +0200 |
| commit | 9a9d5c5880095adeb43a045dca638243c8f946e4 (patch) | |
| tree | 86e0d23af339b3139efab15749aaf5b59aa0965b /crates/rocie-client/src/apis/mod.rs | |
| parent | chore: Initial commit (diff) | |
| download | server-9a9d5c5880095adeb43a045dca638243c8f946e4.zip | |
feat: Provide basic API frame
Diffstat (limited to 'crates/rocie-client/src/apis/mod.rs')
| -rw-r--r-- | crates/rocie-client/src/apis/mod.rs | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/crates/rocie-client/src/apis/mod.rs b/crates/rocie-client/src/apis/mod.rs new file mode 100644 index 0000000..c3f990f --- /dev/null +++ b/crates/rocie-client/src/apis/mod.rs @@ -0,0 +1,117 @@ +use std::error; +use std::fmt; + +#[derive(Debug, Clone)] +pub struct ResponseContent<T> { + pub status: reqwest::StatusCode, + pub content: String, + pub entity: Option<T>, +} + +#[derive(Debug)] +pub enum Error<T> { + Reqwest(reqwest::Error), + Serde(serde_json::Error), + Io(std::io::Error), + ResponseError(ResponseContent<T>), +} + +impl <T> fmt::Display for Error<T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let (module, e) = match self { + Error::Reqwest(e) => ("reqwest", e.to_string()), + Error::Serde(e) => ("serde", e.to_string()), + Error::Io(e) => ("IO", e.to_string()), + Error::ResponseError(e) => ("response", format!("status code {}", e.status)), + }; + write!(f, "error in {}: {}", module, e) + } +} + +impl <T: fmt::Debug> error::Error for Error<T> { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + Some(match self { + Error::Reqwest(e) => e, + Error::Serde(e) => e, + Error::Io(e) => e, + Error::ResponseError(_) => return None, + }) + } +} + +impl <T> From<reqwest::Error> for Error<T> { + fn from(e: reqwest::Error) -> Self { + Error::Reqwest(e) + } +} + +impl <T> From<serde_json::Error> for Error<T> { + fn from(e: serde_json::Error) -> Self { + Error::Serde(e) + } +} + +impl <T> From<std::io::Error> for Error<T> { + fn from(e: std::io::Error) -> Self { + Error::Io(e) + } +} + +pub fn urlencode<T: AsRef<str>>(s: T) -> String { + ::url::form_urlencoded::byte_serialize(s.as_ref().as_bytes()).collect() +} + +pub fn parse_deep_object(prefix: &str, value: &serde_json::Value) -> Vec<(String, String)> { + if let serde_json::Value::Object(object) = value { + let mut params = vec![]; + + for (key, value) in object { + match value { + serde_json::Value::Object(_) => params.append(&mut parse_deep_object( + &format!("{}[{}]", prefix, key), + value, + )), + serde_json::Value::Array(array) => { + for (i, value) in array.iter().enumerate() { + params.append(&mut parse_deep_object( + &format!("{}[{}][{}]", prefix, key, i), + value, + )); + } + }, + serde_json::Value::String(s) => params.push((format!("{}[{}]", prefix, key), s.clone())), + _ => params.push((format!("{}[{}]", prefix, key), value.to_string())), + } + } + + return params; + } + + unimplemented!("Only objects are supported with style=deepObject") +} + +/// Internal use only +/// A content type supported by this client. +#[allow(dead_code)] +enum ContentType { + Json, + Text, + Unsupported(String) +} + +impl From<&str> for ContentType { + fn from(content_type: &str) -> Self { + if content_type.starts_with("application") && content_type.contains("json") { + return Self::Json; + } else if content_type.starts_with("text/plain") { + return Self::Text; + } else { + return Self::Unsupported(content_type.to_string()); + } + } +} + +pub mod api_get_api; +pub mod api_set_api; + +pub mod configuration; |
