diff --git a/src/sbot.rs b/src/sbot.rs index 621fb8e..fd065ca 100644 --- a/src/sbot.rs +++ b/src/sbot.rs @@ -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, 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 = 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