use std::{fmt::Display, str::FromStr}; use serde::{Deserialize, Serialize}; use thiserror::Error; mod operations; mod values; pub use operations::*; use url::Url; use crate::object::GiteratedObject; pub struct InstanceMeta { pub url: String, pub public_key: String, } /// An instance, defined by the URL it can be reached at. /// /// # Textual Format /// An instance's textual format is its URL. /// /// ## Examples /// For the instance `giterated.dev`, the following [`Instance`] initialization /// would be valid: /// /// ``` /// let instance = Instance { /// url: String::from("giterated.dev") /// }; /// /// // This is correct /// assert_eq!(Instance::from_str("giterated.dev").unwrap(), instance); /// ``` #[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] pub struct Instance(pub String); impl GiteratedObject for Instance { fn object_name() -> &'static str { "instance" } fn from_object_str(object_str: &str) -> Result { Ok(Instance::from_str(object_str)?) } fn home_uri(&self) -> String { self.0.clone() } } impl Display for Instance { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str(&self.0.to_string()) } } impl FromStr for Instance { type Err = InstanceParseError; fn from_str(s: &str) -> Result { let with_protocol = format!("wss://{}", s); if Url::parse(&with_protocol).is_ok() { Ok(Self(s.to_string())) } else { Err(InstanceParseError::InvalidFormat) } } } #[derive(Debug, Error)] pub enum InstanceParseError { #[error("invalid format")] InvalidFormat, }