Working on profile info
This commit is contained in:
parent
615431496b
commit
ccc4a3371b
91
src/sbot.rs
91
src/sbot.rs
|
@ -1,4 +1,5 @@
|
|||
//! Sbot type and associated methods.
|
||||
use std::collections::HashMap;
|
||||
use async_std::{
|
||||
net::TcpStream,
|
||||
stream::{Stream, StreamExt},
|
||||
|
@ -281,33 +282,87 @@ impl Sbot {
|
|||
// now we have a stream of about messages with most recent at the front of the vector
|
||||
pin_mut!(about_message_stream);
|
||||
// iterate through the vector looking for most recent about message with the given key
|
||||
let latest_about_message: Result<SsbMessageValue, GolgiError> = about_message_stream
|
||||
let latest_about_message_res: Option<Result<SsbMessageValue, GolgiError>> = about_message_stream
|
||||
// find the first msg that contains the field `key`
|
||||
.find(|res| match res {
|
||||
Ok(msg) => msg.content.get(key).is_some(),
|
||||
Err(_) => false,
|
||||
})
|
||||
.await
|
||||
.ok_or_else(|| {
|
||||
GolgiError::Sbot("error while looking for about message with given key".to_string())
|
||||
})?;
|
||||
let latest_about_value = match latest_about_message {
|
||||
Ok(msg) => {
|
||||
msg
|
||||
// SsbMessageValue -> Option<&Value>
|
||||
.content
|
||||
.get(key)
|
||||
// Option<&Value> -> <Option<&str>
|
||||
.and_then(|value| value.as_str())
|
||||
// Option<&str> -> Option<String>
|
||||
.map(|value| value.to_string())
|
||||
}
|
||||
Err(_) => None,
|
||||
};
|
||||
.await;
|
||||
// Option<Result<SsbMessageValue, GolgiError>> -> Option<SsbMessageValue>
|
||||
let latest_about_message = latest_about_message_res.and_then(|msg| msg.ok());
|
||||
// Option<SsbMessageValue> -> Option<String>
|
||||
let latest_about_value = latest_about_message.and_then(|msg| {
|
||||
msg
|
||||
// SsbMessageValue -> Option<&Value>
|
||||
.content
|
||||
.get(key)
|
||||
// Option<&Value> -> <Option<&str>
|
||||
.and_then(|value| value.as_str())
|
||||
// Option<&str> -> Option<String>
|
||||
.map(|value| value.to_string())
|
||||
});
|
||||
// return value is either `Ok(Some(String))` or `Ok(None)`
|
||||
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", "profile"];
|
||||
// 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 {
|
||||
println!("res: {:?}", res);
|
||||
// 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
|
||||
|
|
Loading…
Reference in New Issue