diff --git a/examples/ssb-client.rs b/examples/ssb-client.rs index 726a280..c76d5f2 100644 --- a/examples/ssb-client.rs +++ b/examples/ssb-client.rs @@ -1,10 +1,10 @@ use std::process; -use kuska_ssb::api::dto::content::{SubsetQuery, TypedMessage, Post}; +use kuska_ssb::api::dto::content::{Post, SubsetQuery, TypedMessage}; use golgi::error::GolgiError; +use golgi::messages::{SsbMessageContent, SsbMessageValue}; use golgi::sbot::Sbot; -use golgi::messages::{SsbMessageValue, SsbMessageContent}; async fn run() -> Result<(), GolgiError> { let mut sbot_client = Sbot::init(None, None).await?; @@ -13,14 +13,14 @@ async fn run() -> Result<(), GolgiError> { println!("{}", id); let post_msg_ref = sbot_client - .publish_description("this is a description") - .await?; + .publish_description("this is a description") + .await?; println!("description: {}", post_msg_ref); let author = "@L/z54cbc8V1kL1/MiBhpEKuN3QJkSoZYNaukny3ghIs=.ed25519".to_string(); println!("Calling create_history"); - let messages : Vec = sbot_client.create_history_stream(author).await?; + let messages: Vec = sbot_client.create_history_stream(author).await?; println!("hist: {:?}", messages); for message in messages { diff --git a/src/error.rs b/src/error.rs index 4dfb3eb..9d93d51 100644 --- a/src/error.rs +++ b/src/error.rs @@ -50,7 +50,7 @@ impl std::error::Error for GolgiError { GolgiError::Rpc(ref err) => Some(err), GolgiError::Sbot(_) => None, GolgiError::SerdeJson(ref err) => Some(err), - GolgiError::ContentTypeDecode(ref err) => None, + GolgiError::ContentTypeDecode(ref _err) => None, } } } @@ -70,7 +70,11 @@ impl std::fmt::Display for GolgiError { GolgiError::Sbot(ref err) => write!(f, "Sbot returned an error response: {}", err), GolgiError::SerdeJson(_) => write!(f, "Failed to serialize JSON slice"), //GolgiError::WhoAmI(ref err) => write!(f, "{}", err), - GolgiError::ContentTypeDecode(ref err) => write!(f, "Failed to decode typed message from ssb message content: {}", err), + GolgiError::ContentTypeDecode(ref err) => write!( + f, + "Failed to decode typed message from ssb message content: {}", + err + ), } } } diff --git a/src/lib.rs b/src/lib.rs index f428e06..7e9a796 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,8 +25,8 @@ //! ``` pub mod error; -pub mod sbot; pub mod messages; +pub mod sbot; pub mod utils; pub use crate::error::GolgiError; diff --git a/src/messages.rs b/src/messages.rs index 764e17c..e90a1c2 100644 --- a/src/messages.rs +++ b/src/messages.rs @@ -1,16 +1,16 @@ -use std::fmt::Debug; -use async_std::io::Read; +//! Message types and conversion methods for `golgi`. + +use std::fmt::Debug; -use serde_json::Value; -use serde::{Serialize, Deserialize}; -use kuska_ssb::api::dto::WhoAmIOut; -use kuska_ssb::feed::{Feed, Message}; -use kuska_ssb::rpc::{RecvMsg, RequestNo, RpcReader}; use kuska_ssb::api::dto::content::TypedMessage; +use serde::{Deserialize, Serialize}; +use serde_json::Value; use crate::error::GolgiError; - +/// This is an alias to TypedMessage in kuska, +/// which is renamed as SsbMessageContent in golgi to fit the naming convention +/// of the other types (SsbMessageKVT and SsbMessageValue) pub type SsbMessageContent = TypedMessage; /// Data type representing the `value` of a message object (`KVT`). More information concerning the @@ -18,6 +18,7 @@ pub type SsbMessageContent = TypedMessage; /// in the [`Metadata` documentation](https://spec.scuttlebutt.nz/feed/messages.html#metadata). #[derive(Serialize, Deserialize, Debug)] #[serde(deny_unknown_fields)] +#[allow(missing_docs)] pub struct SsbMessageValue { pub previous: Option, pub author: String, @@ -29,11 +30,23 @@ pub struct SsbMessageValue { } impl SsbMessageValue { + + /// Gets the type field of the message content if found, + /// and if not returns "none" pub fn get_message_type(&self) -> String { - let msg_type: String = self.content.get("type").map(|msg_type| msg_type.to_string()).unwrap_or_else(|| "none".to_string()); + let msg_type: String = self + .content + .get("type") + .map(|msg_type| msg_type.to_string()) + .unwrap_or_else(|| "none".to_string()); msg_type } + /// Converts the content json value into an SsbMessageContent enum, + /// using the "type" field as a tag to select which variant of the enum + /// to deserialize into. + /// + /// See more info on this here https://serde.rs/enum-representations.html#internally-tagged pub fn into_ssb_message_content(self) -> Result { let m: SsbMessageContent = serde_json::from_value(self.content)?; Ok(m) @@ -45,6 +58,7 @@ impl SsbMessageValue { /// in the [`Metadata` documentation](https://spec.scuttlebutt.nz/feed/messages.html#metadata). #[derive(Serialize, Deserialize, Debug)] #[serde(deny_unknown_fields)] +#[allow(missing_docs)] pub struct SsbKVT { pub key: String, pub value: SsbMessageValue, diff --git a/src/sbot.rs b/src/sbot.rs index 98105ef..23cca11 100644 --- a/src/sbot.rs +++ b/src/sbot.rs @@ -5,23 +5,18 @@ use kuska_handshake::async_std::BoxStream; use kuska_sodiumoxide::crypto::{auth, sign::ed25519}; use kuska_ssb::{ api::{ - dto::{ - content::{SubsetQuery}, - CreateHistoryStreamIn, - }, + dto::{content::SubsetQuery, CreateHistoryStreamIn}, ApiCaller, }, - discovery, keystore, + discovery, + keystore, keystore::OwnedIdentity, rpc::{RpcReader, RpcWriter}, - feed::{Feed, Message} }; -use serde_json::Value; use crate::error::GolgiError; +use crate::messages::{SsbKVT, SsbMessageContent, SsbMessageValue}; use crate::utils; -use crate::messages::{SsbMessageValue, SsbKVT, SsbMessageContent}; - /// The Scuttlebutt identity, keys and configuration parameters for connecting to a local sbot /// instance, as well as handles for calling RPC methods and receiving responses. @@ -104,17 +99,14 @@ impl Sbot { pub async fn whoami(&mut self) -> Result { let req_id = self.client.whoami_req_send().await?; - utils::get_async(&mut self.rpc_reader, req_id, utils::whoami_res_parse) - .await - .map(|whoami| whoami.id) + utils::get_async(&mut self.rpc_reader, req_id, utils::string_res_parse).await } /// Call the `createLogStream` RPC method and return a Vec pub async fn log(&mut self) -> Result { let req_id = self.client.log_req_send().await?; - utils::get_async(&mut self.rpc_reader, req_id, utils::string_res_parse) - .await + utils::get_async(&mut self.rpc_reader, req_id, utils::string_res_parse).await } /// Call the `publish` RPC method and return a message reference. @@ -127,7 +119,7 @@ impl Sbot { pub async fn publish(&mut self, msg: SsbMessageContent) -> Result { let req_id = self.client.publish_req_send(msg).await?; - utils::get_async(&mut self.rpc_reader, req_id, utils::publish_res_parse).await + utils::get_async(&mut self.rpc_reader, req_id, utils::string_res_parse).await } /// Wrapper for publish which constructs and publishes a post message appropriately from a string. @@ -164,7 +156,10 @@ impl Sbot { /// Call the `createHistoryStream` RPC method and return a vector /// of SsbMessageValue. - pub async fn create_history_stream(&mut self, id: String) -> Result, GolgiError> { + pub async fn create_history_stream( + &mut self, + id: String, + ) -> Result, GolgiError> { let args = CreateHistoryStreamIn::new(id); let req_id = self.client.create_history_stream_req_send(&args).await?; utils::get_async_until_eof(&mut self.rpc_reader, req_id, utils::ssb_message_res_parse).await diff --git a/src/utils.rs b/src/utils.rs index ba83b61..637d085 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,24 +1,20 @@ -use std::fmt::Debug; +//! Utility methods for `golgi`. use async_std::io::Read; +use std::fmt::Debug; -use serde_json::Value; -use serde::{Serialize, Deserialize}; -use kuska_ssb::api::dto::WhoAmIOut; -use kuska_ssb::feed::{Feed, Message}; use kuska_ssb::rpc::{RecvMsg, RequestNo, RpcReader}; -use kuska_ssb::api::dto::content::TypedMessage; +use serde_json::Value; use crate::error::GolgiError; use crate::messages::{SsbKVT, SsbMessageValue}; - /// Function to parse an array of bytes (returned by an rpc call) into a KVT. /// /// # Arguments /// /// * `body` - An array of u8 to be parsed. pub fn kvt_res_parse(body: &[u8]) -> Result { - let value: Value = serde_json::from_slice(&body)?; + let value: Value = serde_json::from_slice(body)?; let kvt: SsbKVT = serde_json::from_value(value)?; Ok(kvt) } @@ -54,18 +50,6 @@ pub fn ssb_message_res_parse(body: &[u8]) -> Result } -//pub fn publish_res_parse(body: &[u8]) -> Result { -pub fn publish_res_parse(body: &[u8]) -> Result { - //Ok(serde_json::from_slice(body)?) - // TODO: cleanup with proper error handling etc. - Ok(std::str::from_utf8(body).unwrap().to_string()) -} - -pub fn whoami_res_parse(body: &[u8]) -> Result { - Ok(serde_json::from_slice(body)?) -} - - /// Takes in an rpc request number, and a handling function, /// and waits for an rpc response which matches the request number, /// and then calls the handling function on the response. @@ -93,13 +77,15 @@ where match msg { RecvMsg::RpcResponse(_type, body) => { return f(&body).map_err(|err| err); - }, + } RecvMsg::ErrorResponse(message) => { return Err(GolgiError::Sbot(message)); - }, + } RecvMsg::CancelStreamRespose() => { - return Err(GolgiError::Sbot("sbot returned CancelStreamResponse before any content".to_string())); - }, + return Err(GolgiError::Sbot( + "sbot returned CancelStreamResponse before any content".to_string(), + )); + } _ => {} } } @@ -129,7 +115,7 @@ where F: Fn(&[u8]) -> Result, T: Debug, { - let mut messages: Vec = Vec::new();; + let mut messages: Vec = Vec::new(); loop { let (id, msg) = rpc_reader.recv().await?; if id == req_no { @@ -139,7 +125,7 @@ where match parsed_response { Ok(parsed_message) => { messages.push(parsed_message); - }, + } Err(err) => { return Err(err); } @@ -190,9 +176,7 @@ where RecvMsg::ErrorResponse(message) => { return Err(GolgiError::Sbot(message)); } - RecvMsg::CancelStreamRespose() => { - break - }, + RecvMsg::CancelStreamRespose() => break, _ => {} } }