2022-02-08 09:52:52 +00:00
|
|
|
//! Define peer relationships and query the social graph.
|
|
|
|
//!
|
|
|
|
//! Implements the following methods:
|
|
|
|
//!
|
|
|
|
//! - [`Sbot::block`]
|
2022-03-01 12:19:58 +00:00
|
|
|
//! - [`Sbot::unblock`]
|
2022-02-08 09:52:52 +00:00
|
|
|
//! - [`Sbot::follow`]
|
2022-03-01 12:19:58 +00:00
|
|
|
//! - [`Sbot::unfollow`]
|
2022-02-08 09:52:52 +00:00
|
|
|
//! - [`Sbot::friends_hops`]
|
|
|
|
//! - [`Sbot::friends_is_blocking`]
|
|
|
|
//! - [`Sbot::friends_is_following`]
|
2022-03-01 11:54:52 +00:00
|
|
|
//! - [`Sbot::get_blocks`]
|
2022-02-08 09:52:52 +00:00
|
|
|
//! - [`Sbot::get_follows`]
|
|
|
|
//! - [`Sbot::set_relationship`]
|
|
|
|
|
|
|
|
use crate::{error::GolgiError, messages::SsbMessageContent, sbot::Sbot, utils};
|
|
|
|
|
|
|
|
// re-export friends-related kuska types
|
|
|
|
pub use kuska_ssb::api::dto::content::{FriendsHops, RelationshipQuery};
|
2022-02-07 11:54:47 +00:00
|
|
|
|
|
|
|
impl Sbot {
|
2022-02-14 13:52:23 +00:00
|
|
|
/// Follow a peer.
|
|
|
|
///
|
|
|
|
/// This is a convenience method to publish a contact message with
|
2022-03-01 13:42:40 +00:00
|
|
|
/// following: `true`.
|
2022-02-14 13:52:23 +00:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
2022-05-11 12:14:25 +00:00
|
|
|
/// use golgi::{Sbot, GolgiError, sbot::Keystore};
|
2022-02-14 13:52:23 +00:00
|
|
|
///
|
|
|
|
/// async fn follow_peer() -> Result<(), GolgiError> {
|
2022-05-11 12:14:25 +00:00
|
|
|
/// let mut sbot_client = Sbot::init(Keystore::Patchwork, None, None).await?;
|
2022-02-14 13:52:23 +00:00
|
|
|
///
|
|
|
|
/// 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(())
|
|
|
|
/// }
|
|
|
|
/// ```
|
2022-02-07 11:54:47 +00:00
|
|
|
pub async fn follow(&mut self, contact: &str) -> Result<String, GolgiError> {
|
2022-03-01 13:42:40 +00:00
|
|
|
self.set_relationship(contact, Some(true), None).await
|
2022-02-07 11:54:47 +00:00
|
|
|
}
|
|
|
|
|
2022-03-01 12:19:58 +00:00
|
|
|
/// Unfollow a peer.
|
|
|
|
///
|
|
|
|
/// This is a convenience method to publish a contact message with
|
2022-03-01 13:42:40 +00:00
|
|
|
/// following: `false`.
|
2022-03-01 12:19:58 +00:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
2022-05-11 12:14:25 +00:00
|
|
|
/// use golgi::{Sbot, GolgiError, sbot::Keystore};
|
2022-03-01 12:19:58 +00:00
|
|
|
///
|
|
|
|
/// async fn unfollow_peer() -> Result<(), GolgiError> {
|
2022-05-11 12:14:25 +00:00
|
|
|
/// let mut sbot_client = Sbot::init(Keystore::Patchwork, None, None).await?;
|
2022-03-01 12:19:58 +00:00
|
|
|
///
|
|
|
|
/// let ssb_id = "@zqshk7o2Rpd/OaZ/MxH6xXONgonP1jH+edK9+GZb/NY=.ed25519";
|
|
|
|
///
|
|
|
|
/// match sbot_client.unfollow(ssb_id).await {
|
|
|
|
/// Ok(msg_ref) => {
|
|
|
|
/// println!("unfollow msg reference is: {}", msg_ref)
|
|
|
|
/// },
|
|
|
|
/// Err(e) => eprintln!("failed to unfollow {}: {}", ssb_id, e)
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// Ok(())
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
pub async fn unfollow(&mut self, contact: &str) -> Result<String, GolgiError> {
|
2022-03-01 13:42:40 +00:00
|
|
|
self.set_relationship(contact, Some(false), None).await
|
2022-03-01 12:19:58 +00:00
|
|
|
}
|
|
|
|
|
2022-02-14 13:52:23 +00:00
|
|
|
/// Block a peer.
|
|
|
|
///
|
|
|
|
/// This is a convenience method to publish a contact message with
|
|
|
|
/// following: `false` and blocking: `true`.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
2022-05-11 12:14:25 +00:00
|
|
|
/// use golgi::{Sbot, GolgiError, sbot::Keystore};
|
2022-02-14 13:52:23 +00:00
|
|
|
///
|
|
|
|
/// async fn block_peer() -> Result<(), GolgiError> {
|
2022-05-11 12:14:25 +00:00
|
|
|
/// let mut sbot_client = Sbot::init(Keystore::Patchwork, None, None).await?;
|
2022-02-14 13:52:23 +00:00
|
|
|
///
|
|
|
|
/// 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(())
|
|
|
|
/// }
|
|
|
|
/// ```
|
2022-02-07 11:54:47 +00:00
|
|
|
pub async fn block(&mut self, contact: &str) -> Result<String, GolgiError> {
|
2022-03-01 13:42:40 +00:00
|
|
|
// we want to unfollow and block
|
|
|
|
self.set_relationship(contact, Some(false), Some(true))
|
|
|
|
.await
|
2022-02-07 11:54:47 +00:00
|
|
|
}
|
|
|
|
|
2022-03-01 12:19:58 +00:00
|
|
|
/// Unblock a peer.
|
|
|
|
///
|
|
|
|
/// This is a convenience method to publish a contact message with
|
2022-03-01 13:42:40 +00:00
|
|
|
/// blocking: `false`.
|
2022-03-01 12:19:58 +00:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
2022-05-11 12:14:25 +00:00
|
|
|
/// use golgi::{Sbot, GolgiError, sbot::Keystore};
|
2022-03-01 12:19:58 +00:00
|
|
|
///
|
|
|
|
/// async fn unblock_peer() -> Result<(), GolgiError> {
|
2022-05-11 12:14:25 +00:00
|
|
|
/// let mut sbot_client = Sbot::init(Keystore::Patchwork, None, None).await?;
|
2022-03-01 12:19:58 +00:00
|
|
|
///
|
|
|
|
/// let ssb_id = "@zqshk7o2Rpd/OaZ/MxH6xXONgonP1jH+edK9+GZb/NY=.ed25519";
|
|
|
|
///
|
|
|
|
/// match sbot_client.unblock(ssb_id).await {
|
|
|
|
/// Ok(msg_ref) => {
|
|
|
|
/// println!("unblock msg reference is: {}", msg_ref)
|
|
|
|
/// },
|
|
|
|
/// Err(e) => eprintln!("failed to unblock {}: {}", ssb_id, e)
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// Ok(())
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
pub async fn unblock(&mut self, contact: &str) -> Result<String, GolgiError> {
|
2022-03-01 13:42:40 +00:00
|
|
|
self.set_relationship(contact, None, Some(false)).await
|
2022-03-01 12:19:58 +00:00
|
|
|
}
|
|
|
|
|
2022-02-14 13:52:23 +00:00
|
|
|
/// Publish a contact message defining the relationship for a peer.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
2022-05-11 12:14:25 +00:00
|
|
|
/// use golgi::{Sbot, GolgiError, sbot::Keystore};
|
2022-02-14 13:52:23 +00:00
|
|
|
///
|
|
|
|
/// async fn relationship() -> Result<(), GolgiError> {
|
2022-05-11 12:14:25 +00:00
|
|
|
/// let mut sbot_client = Sbot::init(Keystore::Patchwork, None, None).await?;
|
2022-02-14 13:52:23 +00:00
|
|
|
///
|
|
|
|
/// let ssb_id = "@zqshk7o2Rpd/OaZ/MxH6xXONgonP1jH+edK9+GZb/NY=.ed25519";
|
2022-03-01 13:42:40 +00:00
|
|
|
/// let following = Some(true);
|
|
|
|
/// // Could also be `None` to only publish the following relationship.
|
|
|
|
/// let blocking = Some(false);
|
2022-02-14 13:52:23 +00:00
|
|
|
///
|
|
|
|
/// 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(())
|
|
|
|
/// }
|
|
|
|
/// ```
|
2022-02-07 11:54:47 +00:00
|
|
|
pub async fn set_relationship(
|
|
|
|
&mut self,
|
|
|
|
contact: &str,
|
2022-03-01 13:42:40 +00:00
|
|
|
following: Option<bool>,
|
|
|
|
blocking: Option<bool>,
|
2022-02-07 11:54:47 +00:00
|
|
|
) -> Result<String, GolgiError> {
|
|
|
|
let msg = SsbMessageContent::Contact {
|
|
|
|
contact: Some(contact.to_string()),
|
2022-03-01 13:42:40 +00:00
|
|
|
following,
|
|
|
|
blocking,
|
2022-02-07 11:54:47 +00:00
|
|
|
autofollow: None,
|
|
|
|
};
|
|
|
|
self.publish(msg).await
|
|
|
|
}
|
|
|
|
|
2022-02-14 13:52:23 +00:00
|
|
|
/// 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
|
2022-05-11 12:14:25 +00:00
|
|
|
/// use golgi::{Sbot, GolgiError, api::friends::RelationshipQuery, sbot::Keystore};
|
2022-02-14 13:52:23 +00:00
|
|
|
///
|
|
|
|
/// async fn relationship() -> Result<(), GolgiError> {
|
2022-05-11 12:14:25 +00:00
|
|
|
/// let mut sbot_client = Sbot::init(Keystore::Patchwork, None, None).await?;
|
2022-02-14 13:52:23 +00:00
|
|
|
///
|
|
|
|
/// 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(())
|
|
|
|
/// }
|
|
|
|
/// ```
|
2022-02-07 11:54:47 +00:00
|
|
|
pub async fn friends_is_following(
|
|
|
|
&mut self,
|
|
|
|
args: RelationshipQuery,
|
|
|
|
) -> Result<String, GolgiError> {
|
|
|
|
let mut sbot_connection = self.get_sbot_connection().await?;
|
|
|
|
let req_id = sbot_connection
|
|
|
|
.client
|
|
|
|
.friends_is_following_req_send(args)
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
utils::get_async(
|
|
|
|
&mut sbot_connection.rpc_reader,
|
|
|
|
req_id,
|
|
|
|
utils::string_res_parse,
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
}
|
|
|
|
|
2022-02-14 13:52:23 +00:00
|
|
|
/// 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
|
2022-05-11 12:14:25 +00:00
|
|
|
/// use golgi::{Sbot, GolgiError, api::friends::RelationshipQuery, sbot::Keystore};
|
2022-02-14 13:52:23 +00:00
|
|
|
///
|
|
|
|
/// async fn relationship() -> Result<(), GolgiError> {
|
2022-05-11 12:14:25 +00:00
|
|
|
/// let mut sbot_client = Sbot::init(Keystore::Patchwork, None, None).await?;
|
2022-02-14 13:52:23 +00:00
|
|
|
///
|
|
|
|
/// 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(())
|
|
|
|
/// }
|
|
|
|
/// ```
|
2022-02-07 11:54:47 +00:00
|
|
|
pub async fn friends_is_blocking(
|
|
|
|
&mut self,
|
|
|
|
args: RelationshipQuery,
|
|
|
|
) -> Result<String, GolgiError> {
|
|
|
|
let mut sbot_connection = self.get_sbot_connection().await?;
|
|
|
|
let req_id = sbot_connection
|
|
|
|
.client
|
|
|
|
.friends_is_blocking_req_send(args)
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
utils::get_async(
|
|
|
|
&mut sbot_connection.rpc_reader,
|
|
|
|
req_id,
|
2022-03-01 11:54:52 +00:00
|
|
|
utils::string_res_parse,
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Get a list of peers blocked by the local peer.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
2022-05-11 12:14:25 +00:00
|
|
|
/// use golgi::{Sbot, GolgiError, sbot::Keystore};
|
2022-03-01 11:54:52 +00:00
|
|
|
///
|
|
|
|
/// async fn follows() -> Result<(), GolgiError> {
|
2022-05-11 12:14:25 +00:00
|
|
|
/// let mut sbot_client = Sbot::init(Keystore::Patchwork, None, None).await?;
|
2022-03-01 11:54:52 +00:00
|
|
|
///
|
|
|
|
/// let follows = sbot_client.get_blocks().await?;
|
|
|
|
///
|
|
|
|
/// if follows.is_empty() {
|
|
|
|
/// println!("we do not block any peers")
|
|
|
|
/// } else {
|
|
|
|
/// follows.iter().for_each(|peer| println!("we block {}", peer))
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// Ok(())
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
pub async fn get_blocks(&mut self) -> Result<Vec<String>, GolgiError> {
|
|
|
|
let mut sbot_connection = self.get_sbot_connection().await?;
|
|
|
|
let req_id = sbot_connection.client.friends_blocks_req_send().await?;
|
|
|
|
utils::get_source_until_eof(
|
|
|
|
&mut sbot_connection.rpc_reader,
|
|
|
|
req_id,
|
2022-02-07 11:54:47 +00:00
|
|
|
utils::string_res_parse,
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
}
|
|
|
|
|
2022-02-14 13:52:23 +00:00
|
|
|
/// Get a list of peers followed by the local peer.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
2022-05-11 12:14:25 +00:00
|
|
|
/// use golgi::{Sbot, GolgiError, sbot::Keystore};
|
2022-02-14 13:52:23 +00:00
|
|
|
///
|
|
|
|
/// async fn follows() -> Result<(), GolgiError> {
|
2022-05-11 12:14:25 +00:00
|
|
|
/// let mut sbot_client = Sbot::init(Keystore::Patchwork, None, None).await?;
|
2022-02-14 13:52:23 +00:00
|
|
|
///
|
|
|
|
/// 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(())
|
|
|
|
/// }
|
|
|
|
/// ```
|
2022-02-07 11:54:47 +00:00
|
|
|
pub async fn get_follows(&mut self) -> Result<Vec<String>, GolgiError> {
|
|
|
|
self.friends_hops(FriendsHops {
|
2022-02-16 12:17:28 +00:00
|
|
|
max: 0,
|
2022-02-07 11:54:47 +00:00
|
|
|
start: None,
|
|
|
|
reverse: Some(false),
|
|
|
|
})
|
|
|
|
.await
|
|
|
|
}
|
|
|
|
|
2022-02-14 13:52:23 +00:00
|
|
|
/// 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
|
2022-05-11 12:14:25 +00:00
|
|
|
/// use golgi::{Sbot, GolgiError, sbot::Keystore};
|
2022-02-14 13:52:23 +00:00
|
|
|
///
|
|
|
|
/// async fn followers() -> Result<(), GolgiError> {
|
2022-05-11 12:14:25 +00:00
|
|
|
/// let mut sbot_client = Sbot::init(Keystore::Patchwork, None, None).await?;
|
2022-02-14 13:52:23 +00:00
|
|
|
///
|
|
|
|
/// // 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(())
|
|
|
|
/// }
|
|
|
|
/// ```
|
2022-02-07 12:07:48 +00:00
|
|
|
async fn _get_followers(&mut self) -> Result<Vec<String>, GolgiError> {
|
2022-02-07 11:54:47 +00:00
|
|
|
self.friends_hops(FriendsHops {
|
2022-02-16 12:17:28 +00:00
|
|
|
max: 0,
|
2022-02-07 11:54:47 +00:00
|
|
|
start: None,
|
|
|
|
reverse: Some(true),
|
|
|
|
})
|
|
|
|
.await
|
|
|
|
}
|
|
|
|
|
2022-02-14 13:52:23 +00:00
|
|
|
/// Get a list of peers within the specified hops range.
|
|
|
|
///
|
|
|
|
/// A `RelationshipQuery` `struct` must be defined and passed into this method.
|
2022-02-07 11:54:47 +00:00
|
|
|
///
|
2022-02-16 12:17:28 +00:00
|
|
|
/// Hops = 0 returns a list of peers followed by the local identity.
|
|
|
|
/// Those peers may or may not be mutual follows (ie. friends).
|
|
|
|
///
|
|
|
|
/// Hops = 1 includes the peers followed by the peers we follow.
|
|
|
|
/// For example, if the local identity follows Aiko and Aiko follows
|
|
|
|
/// Bridgette and Chris, hops = 1 will return a list including the public
|
|
|
|
/// keys for Aiko, Bridgette and Chris (even though Bridgette and Chris
|
|
|
|
/// are not followed by the local identity).
|
|
|
|
///
|
|
|
|
/// When reverse = True, hops = 0 should return a list of peers who
|
|
|
|
/// follow the local identity, ie. followers (but this is not currently
|
|
|
|
/// implemented in go-sbot).
|
2022-02-14 13:52:23 +00:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
2022-05-11 12:14:25 +00:00
|
|
|
/// use golgi::{Sbot, GolgiError, api::friends::FriendsHops, sbot::Keystore};
|
2022-02-14 13:52:23 +00:00
|
|
|
///
|
|
|
|
/// async fn peers_within_range() -> Result<(), GolgiError> {
|
2022-05-11 12:14:25 +00:00
|
|
|
/// let mut sbot_client = Sbot::init(Keystore::Patchwork, None, None).await?;
|
2022-02-14 13:52:23 +00:00
|
|
|
///
|
|
|
|
/// 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(())
|
|
|
|
/// }
|
|
|
|
/// ```
|
2022-02-07 11:54:47 +00:00
|
|
|
pub async fn friends_hops(&mut self, args: FriendsHops) -> Result<Vec<String>, GolgiError> {
|
|
|
|
let mut sbot_connection = self.get_sbot_connection().await?;
|
|
|
|
let req_id = sbot_connection.client.friends_hops_req_send(args).await?;
|
|
|
|
utils::get_source_until_eof(
|
|
|
|
&mut sbot_connection.rpc_reader,
|
|
|
|
req_id,
|
|
|
|
utils::string_res_parse,
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
}
|
|
|
|
}
|