diff --git a/Cargo.lock b/Cargo.lock index 3f013c7..f9f0a20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,241 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "async-trait" +version = "0.1.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "getrandom" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + [[package]] name = "kordophone" version = "0.1.0" +dependencies = [ + "async-trait", + "serde", + "serde_json", + "time", + "uuid", +] + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro2" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "serde" +version = "1.0.198" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.198" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.116" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "syn" +version = "2.0.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "uuid" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +dependencies = [ + "getrandom", + "rand", + "uuid-macro-internal", +] + +[[package]] +name = "uuid-macro-internal" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9881bea7cbe687e36c9ab3b778c36cd0487402e270304e8b1296d5085303c1a2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" diff --git a/kordophone/Cargo.toml b/kordophone/Cargo.toml index 7d1a124..f604194 100644 --- a/kordophone/Cargo.toml +++ b/kordophone/Cargo.toml @@ -6,3 +6,8 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +async-trait = "0.1.80" +serde = { version = "1.0.152", features = ["derive"] } +serde_json = "1.0.91" +time = { version = "0.3.17", features = ["parsing", "serde"] } +uuid = { version = "1.6.1", features = ["v4", "fast-rng", "macro-diagnostics"] } diff --git a/kordophone/src/api/mod.rs b/kordophone/src/api/mod.rs index 1e2553d..c5b2ac8 100644 --- a/kordophone/src/api/mod.rs +++ b/kordophone/src/api/mod.rs @@ -1,12 +1,14 @@ +use async_trait::async_trait; +pub use crate::model::Conversation; +#[async_trait] pub trait APIInterface { - fn version(&self) -> String; + type Error; + + // (GET) /version + async fn get_version(&self) -> Result; + + // (GET) /conversations + async fn get_conversations(&self) -> Result, Self::Error>; } -pub struct TestClient {} - -impl APIInterface for TestClient { - fn version(&self) -> String { - return "KordophoneTest-1.0".to_string() - } -} diff --git a/kordophone/src/lib.rs b/kordophone/src/lib.rs index 203b1a5..c0ba5bc 100644 --- a/kordophone/src/lib.rs +++ b/kordophone/src/lib.rs @@ -1,16 +1,7 @@ mod api; -pub use self::api::TestClient; +pub mod model; pub use self::api::APIInterface; #[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_version() { - let client = TestClient{}; - let version = client.version(); - assert_eq!(version, "KordophoneTest-1.0"); - } -} +pub mod tests; diff --git a/kordophone/src/model/conversation.rs b/kordophone/src/model/conversation.rs new file mode 100644 index 0000000..fdca656 --- /dev/null +++ b/kordophone/src/model/conversation.rs @@ -0,0 +1,86 @@ +use serde::Deserialize; +use time::OffsetDateTime; +use uuid::Uuid; + +#[derive(Debug, Clone, Deserialize)] +pub struct Conversation { + pub guid: String, + + #[serde(with = "time::serde::iso8601")] + pub date: OffsetDateTime, + + #[serde(rename = "unreadCount")] + pub unread_count: i32, + + #[serde(rename = "lastMessagePreview")] + pub last_message_preview: Option, + + #[serde(rename = "participantDisplayNames")] + pub participant_display_names: Vec, + + #[serde(rename = "displayName")] + pub display_name: Option, +} + +impl Conversation { + pub fn builder() -> ConversationBuilder { + ConversationBuilder::new() + } +} + +#[derive(Default)] +pub struct ConversationBuilder { + guid: Option, + date: Option, + unread_count: Option, + last_message_preview: Option, + participant_display_names: Option>, + display_name: Option, +} + +impl ConversationBuilder { + pub fn new() -> Self { + Self::default() + } + + pub fn guid(mut self, guid: String) -> Self { + self.guid = Some(guid); + self + } + + pub fn date(mut self, date: OffsetDateTime) -> Self { + self.date = Some(date); + self + } + + pub fn unread_count(mut self, unread_count: i32) -> Self { + self.unread_count = Some(unread_count); + self + } + + pub fn last_message_preview(mut self, last_message_preview: String) -> Self { + self.last_message_preview = Some(last_message_preview); + self + } + + pub fn participant_display_names(mut self, participant_display_names: Vec) -> Self { + self.participant_display_names = Some(participant_display_names); + self + } + + pub fn display_name(mut self, display_name: T) -> Self where T: Into { + self.display_name = Some(display_name.into()); + self + } + + pub fn build(self) -> Conversation { + Conversation { + guid: self.guid.unwrap_or(Uuid::new_v4().to_string()), + date: self.date.unwrap_or(OffsetDateTime::now_utc()), + unread_count: self.unread_count.unwrap_or(0), + last_message_preview: self.last_message_preview, + participant_display_names: self.participant_display_names.unwrap_or(vec![]), + display_name: self.display_name, + } + } +} diff --git a/kordophone/src/model/mod.rs b/kordophone/src/model/mod.rs new file mode 100644 index 0000000..291ac75 --- /dev/null +++ b/kordophone/src/model/mod.rs @@ -0,0 +1,3 @@ + +pub mod conversation; +pub use conversation::Conversation; diff --git a/kordophone/src/tests/mod.rs b/kordophone/src/tests/mod.rs new file mode 100644 index 0000000..07f905c --- /dev/null +++ b/kordophone/src/tests/mod.rs @@ -0,0 +1,22 @@ +mod test_client; +use self::test_client::TestClient; +use crate::APIInterface; + +pub mod api_interface { + use super::*; + + #[test] + fn test_version() { + let client = TestClient{}; + let version = client.get_version(); + assert_eq!(version, "KordophoneTest-1.0"); + } + + #[test] + fn test_conversations() { + let client = TestClient{}; + let conversations = client.get_conversations(); + assert_eq!(conversations.len(), 1); + assert_eq!(conversations[0].display_name, Some("Test Conversation".to_string())); + } +} \ No newline at end of file diff --git a/kordophone/src/tests/test_client.rs b/kordophone/src/tests/test_client.rs new file mode 100644 index 0000000..7a50cef --- /dev/null +++ b/kordophone/src/tests/test_client.rs @@ -0,0 +1,16 @@ +pub use crate::APIInterface; +use crate::model::Conversation; + +pub struct TestClient {} + +impl APIInterface for TestClient { + fn get_version(&self) -> String { + return "KordophoneTest-1.0".to_string() + } + + fn get_conversations(&self) -> Vec { + let mut conversations = Vec::new(); + conversations.push(Conversation::builder().display_name("Test Conversation").build()); + conversations + } +}