diff --git a/src/api/friends.rs b/src/api/friends.rs index 14d1268..63c73af 100644 --- a/src/api/friends.rs +++ b/src/api/friends.rs @@ -16,20 +16,88 @@ use crate::{error::GolgiError, messages::SsbMessageContent, sbot::Sbot, utils}; pub use kuska_ssb::api::dto::content::{FriendsHops, RelationshipQuery}; impl Sbot { - /// Convenience method to set a relationship with following: `true`, - /// blocking: `false`. + /// Follow a peer. + /// + /// This is a convenience method to publish a contact message with + /// following: `true` and blocking: `false`. + /// + /// # Example + /// + /// ```rust + /// use golgi::{Sbot, GolgiError}; + /// + /// async fn follow_peer() -> Result<(), GolgiError> { + /// let mut sbot_client = Sbot::init(None, None).await?; + /// + /// let ssb_id = "@zqshk7o2Rpd/OaZ/MxH6xXONgonP1jH+edK9+GZb/NY=.ed25519"; + /// + /// match sbot_client.follow(ssb_id).await { + /// Ok(msg_ref) => { + /// println!("follow msg reference is: {}", msg_ref) + /// }, + /// Err(e) => eprintln!("failed to follow {}: {}", ssb_id, e) + /// } + /// + /// Ok(()) + /// } + /// ``` pub async fn follow(&mut self, contact: &str) -> Result { self.set_relationship(contact, true, false).await } - /// Convenience method to set a relationship with following: `false`, - /// blocking: `true`. + /// Block a peer. + /// + /// This is a convenience method to publish a contact message with + /// following: `false` and blocking: `true`. + /// + /// # Example + /// + /// ```rust + /// use golgi::{Sbot, GolgiError}; + /// + /// async fn block_peer() -> Result<(), GolgiError> { + /// let mut sbot_client = Sbot::init(None, None).await?; + /// + /// let ssb_id = "@zqshk7o2Rpd/OaZ/MxH6xXONgonP1jH+edK9+GZb/NY=.ed25519"; + /// + /// match sbot_client.block(ssb_id).await { + /// Ok(msg_ref) => { + /// println!("block msg reference is: {}", msg_ref) + /// }, + /// Err(e) => eprintln!("failed to block {}: {}", ssb_id, e) + /// } + /// + /// Ok(()) + /// } + /// ``` pub async fn block(&mut self, contact: &str) -> Result { self.set_relationship(contact, false, true).await } - /// Publish a contact relationship to the given peer (with ssb_id) with - /// the given state. + /// Publish a contact message defining the relationship for a peer. + /// + /// # Example + /// + /// ```rust + /// use golgi::{Sbot, GolgiError}; + /// + /// async fn relationship() -> Result<(), GolgiError> { + /// let mut sbot_client = Sbot::init(None, None).await?; + /// + /// let ssb_id = "@zqshk7o2Rpd/OaZ/MxH6xXONgonP1jH+edK9+GZb/NY=.ed25519"; + /// let following = true; + /// let blocking = false; + /// + /// match sbot_client.set_relationship(ssb_id, following, blocking).await { + /// Ok(msg_ref) => { + /// println!("contact msg reference is: {}", msg_ref) + /// }, + /// Err(e) => eprintln!("failed to set relationship for {}: {}", ssb_id, e) + /// } + /// + /// Ok(()) + /// } + /// ``` pub async fn set_relationship( &mut self, contact: &str, @@ -45,8 +113,38 @@ impl Sbot { self.publish(msg).await } - /// Call the `friends isFollowing` RPC method and return a message reference. - /// Returns `true` if `src_id` is following `dest_id` and `false` otherwise. + /// Get the follow status of two peers (ie. does one peer follow the other?). + /// + /// A `RelationshipQuery` `struct` must be defined and passed into this method. + /// + /// # Example + /// + /// ```rust + /// use golgi::{Sbot, GolgiError, api::friends::RelationshipQuery}; + /// + /// async fn relationship() -> Result<(), GolgiError> { + /// let mut sbot_client = Sbot::init(None, None).await?; + /// + /// let peer_a = "@zqshk7o2Rpd/OaZ/MxH6xXONgonP1jH+edK9+GZb/NY=.ed25519"; + /// let peer_b = "@3QoWCcy46X9a4jTnOl8m3+n1gKfbsukWuODDxNGN0W8=.ed25519"; + /// + /// let query = RelationshipQuery { + /// source: peer_a.to_string(), + /// dest: peer_b.to_string(), + /// }; + /// + /// match sbot_client.friends_is_following(query).await { + /// Ok(following) if following == "true" => { + /// println!("{} is following {}", peer_a, peer_b) + /// }, + /// Ok(_) => println!("{} is not following {}", peer_a, peer_b), + /// Err(e) => eprintln!("failed to query relationship status for {} and {}: {}", peer_a, + /// peer_b, e) + /// } + /// + /// Ok(()) + /// } + /// ``` pub async fn friends_is_following( &mut self, args: RelationshipQuery, @@ -65,8 +163,38 @@ impl Sbot { .await } - /// Call the `friends isblocking` RPC method and return a message reference. - /// Returns `true` if `src_id` is blocking `dest_id` and `false` otherwise. + /// Get the block status of two peers (ie. does one peer block the other?). + /// + /// A `RelationshipQuery` `struct` must be defined and passed into this method. + /// + /// # Example + /// + /// ```rust + /// use golgi::{Sbot, GolgiError, api::friends::RelationshipQuery}; + /// + /// async fn relationship() -> Result<(), GolgiError> { + /// let mut sbot_client = Sbot::init(None, None).await?; + /// + /// let peer_a = "@zqshk7o2Rpd/OaZ/MxH6xXONgonP1jH+edK9+GZb/NY=.ed25519"; + /// let peer_b = "@3QoWCcy46X9a4jTnOl8m3+n1gKfbsukWuODDxNGN0W8=.ed25519"; + /// + /// let query = RelationshipQuery { + /// source: peer_a.to_string(), + /// dest: peer_b.to_string(), + /// }; + /// + /// match sbot_client.friends_is_blocking(query).await { + /// Ok(blocking) if blocking == "true" => { + /// println!("{} is blocking {}", peer_a, peer_b) + /// }, + /// Ok(_) => println!("{} is not blocking {}", peer_a, peer_b), + /// Err(e) => eprintln!("failed to query relationship status for {} and {}: {}", peer_a, + /// peer_b, e) + /// } + /// + /// Ok(()) + /// } + /// ``` pub async fn friends_is_blocking( &mut self, args: RelationshipQuery, @@ -85,7 +213,27 @@ impl Sbot { .await } - /// Return a Vec where each element is a peer you are following. + /// Get a list of peers followed by the local peer. + /// + /// # Example + /// + /// ```rust + /// use golgi::{Sbot, GolgiError}; + /// + /// async fn follows() -> Result<(), GolgiError> { + /// let mut sbot_client = Sbot::init(None, None).await?; + /// + /// let follows = sbot_client.get_follows().await?; + /// + /// if follows.is_empty() { + /// println!("we do not follow any peers") + /// } else { + /// follows.iter().for_each(|peer| println!("we follow {}", peer)) + /// } + /// + /// Ok(()) + /// } + /// ``` pub async fn get_follows(&mut self) -> Result, GolgiError> { self.friends_hops(FriendsHops { max: 1, @@ -95,10 +243,33 @@ impl Sbot { .await } - // Gets a Vec where each element is a peer who follows you - /// TODO: currently this method is not working - /// go-sbot does not seem to listen to the reverse=True parameter - /// and just returns follows. + /// Get a list of peers following the local peer. + /// + /// NOTE: this method is not currently working as expected. + /// + /// go-sbot does not currently implement the `reverse=True` parameter. + /// As a result, the parameter is ignored and this method returns follows + /// instead of followers. + /// + /// # Example + /// + /// ```rust + /// use golgi::{Sbot, GolgiError}; + /// + /// async fn followers() -> Result<(), GolgiError> { + /// let mut sbot_client = Sbot::init(None, None).await?; + /// + /// // let followers = sbot_client.get_followers().await?; + /// + /// // if followers.is_empty() { + /// // println!("no peers follow us") + /// // } else { + /// // followers.iter().for_each(|peer| println!("{} is following us", peer)) + /// // } + /// + /// Ok(()) + /// } + /// ``` async fn _get_followers(&mut self) -> Result, GolgiError> { self.friends_hops(FriendsHops { max: 1, @@ -108,11 +279,40 @@ impl Sbot { .await } - /// Call the `friends hops` RPC method and return a Vector - /// where each element of the vector is the ssb_id of a peer. + /// Get a list of peers within the specified hops range. + /// + /// A `RelationshipQuery` `struct` must be defined and passed into this method. /// /// When opts.reverse = True, it should return peers who are following you - /// (but this is currently not working). + /// (but this is not currently working). + /// + /// # Example + /// + /// ```rust + /// use golgi::{Sbot, GolgiError, api::friends::FriendsHops}; + /// + /// async fn peers_within_range() -> Result<(), GolgiError> { + /// let mut sbot_client = Sbot::init(None, None).await?; + /// + /// let hops = 2; + /// + /// let query = FriendsHops { + /// max: hops, + /// reverse: Some(false), + /// start: None, + /// }; + /// + /// let peers = sbot_client.friends_hops(query).await?; + /// + /// if peers.is_empty() { + /// println!("no peers found within {} hops", hops) + /// } else { + /// peers.iter().for_each(|peer| println!("{} is within {} hops", peer, hops)) + /// } + /// + /// Ok(()) + /// } + /// ``` pub async fn friends_hops(&mut self, args: FriendsHops) -> Result, GolgiError> { let mut sbot_connection = self.get_sbot_connection().await?; let req_id = sbot_connection.client.friends_hops_req_send(args).await?;