Add get_profile_info function #13

Merged
notplants merged 3 commits from get_profile_info into main 2022-01-13 15:05:35 +00:00

View File

@ -1,4 +1,5 @@
//! Sbot type and associated methods.
use std::collections::HashMap;
use async_std::{
net::TcpStream,
stream::{Stream, StreamExt},
@ -302,6 +303,62 @@ impl Sbot {
Ok(latest_about_value)
}
/// Get HashMap of profile info for given user
/// by iteratively searching through a stream of about messages,
/// in order of recency,
/// until we find all about messages for all needed info
/// or reach the end of the stream.
pub async fn get_profile_info(
&mut self,
ssb_id: &str
) -> Result<HashMap<String, String>, GolgiError> {
// get about_message_stream
let about_message_stream = self.get_about_message_stream(ssb_id).await?;
// now we have a stream of about messages with most recent at the front of the vector
pin_mut!(about_message_stream); // needed for iteration
let mut profile_info: HashMap<String, String> = HashMap::new();
// these are the about message keys we are looking for
// as we find values for each of these keys,
// we will remove them from this vector (as we are no longer searching for them)
let mut keys_to_search_for = vec!["name", "description", "image"];
// iterate through the stream while it still has more values and
// we still have keys we are looking for
while let Some(res) = about_message_stream.next().await {
// if there are no more keys we are looking for, then we are done
if keys_to_search_for.len() == 0 {
break
}
// if there are still keys we are looking for, then continue searching
match res {
Ok(msg) => {
// for each key we are searching for, check if this about
// message contains a value for that key
for key in &keys_to_search_for.clone() {
let option_val = msg.content.get(key)
.and_then(|val| val.as_str())
.map(|val| val.to_string());
match option_val {
Some(val) => {
// if a value is found, then insert it
profile_info.insert(key.to_string(), val);
// remove this key fom keys_to_search_for, since we are no longer searching for it
keys_to_search_for.retain(|val| val != key)
}
None => {
continue
}
}
}
}
Err(err) => {
// skip errors
continue
}
}
}
Ok(profile_info)
}
/// Get latest about name from given user
///
/// # Arguments