Add publish_own_name, publish_own_description, get_description #6

Merged
notplants merged 3 commits from publish_own_name into main 2021-11-15 13:31:55 +00:00
1 changed files with 78 additions and 5 deletions

View File

@ -190,7 +190,7 @@ impl Sbot {
}
}
/* GET NAME */
/* GET ABOUT MESSAGES */
/// Return latest name assignment from `about` msgs (the name in this case is for the public key
/// associated with the local sbot instance).
@ -221,6 +221,35 @@ impl Sbot {
}
}
/// Return latest description assignment from `about` msgs
/// (the description associated with the public key of the local sbot instance).
///
/// Calls `sbotcli bytype --limit 10 --reverse about`. On success: parses the `stdout` to extract the
/// `description` and returns it. On error: returns the `stderr` output with a description.
///
pub fn get_description(&self) -> Result<Option<String>, SbotCliError> {
let output = Command::new(&self.sbotcli_path)
.arg("bytype")
.arg("--limit")
.arg("10")
.arg("--reverse")
.arg("about")
.output()?;
if output.status.success() {
let stdout = String::from_utf8(output.stdout)?;
let description = utils::regex_finder(r#""description": "(.*)""#, &stdout)?;
Ok(description)
} else {
let stderr = std::str::from_utf8(&output.stderr)?;
// TODO: create a more generic error variant
Err(SbotCliError::GetAboutMsgs(format!(
"Error fetching about messages: {}",
stderr
)))
}
}
/* INVITES */
/// Accept an invite code (trigger a mutual follow with the peer who generated the invite).
@ -347,7 +376,8 @@ impl Sbot {
/// # Arguments
///
/// * `name` - A string slice representing a profile name (bio)
/// * `id` - A string slice representing an id (profile reference / public key)
/// * `id` - A string slice representing the id (profile reference / public key)
notplants marked this conversation as resolved Outdated
Outdated
Review

Hmm this is a bit clumsy. Might be better as:

/// * `id` - A string slice representing the id (profile reference / public key) of the profile being named

Or:

/// * `id` - A string slice representing the id (profile reference / public key) of the one being named

Hmm this is a bit clumsy. Might be better as: ```/// * `id` - A string slice representing the id (profile reference / public key) of the profile being named``` Or: ```/// * `id` - A string slice representing the id (profile reference / public key) of the one being named```
/// of the profile being named
///
pub fn publish_name(&self, id: &str, name: &str) -> Result<String, SbotCliError> {
let output = Command::new(&self.sbotcli_path)
@ -371,6 +401,41 @@ impl Sbot {
}
}
/// Publish an about message with a name for one's own profile,
/// using whoami to find your own id.
///
/// Calls `sbotcli publish about --name [name] [self_id]`.
/// passing the id of the currently running sbot as self_id.
/// On success: trims the trailing whitespace from `stdout` and returns the message reference.
/// On error: returns the `stderr` output with a description.
///
/// # Arguments
///
/// * `name` - A string slice of the new name you would like to self-identify with
///
pub fn publish_own_name(&self, name: &str) -> Result<String, SbotCliError> {
let self_id = &self.whoami()?;
self.publish_name(name, self_id)
}
/// Publish an about message with a description for one's own profile,
/// using whoami to find your own id.
///
/// Calls `sbotcli publish about --description [description] [self_id]`.
/// passing the id of the currently running sbot as self_id.
/// On success: trims the trailing whitespace from `stdout` and returns the message reference.
/// On error: returns the `stderr` output with a description.
///
/// # Arguments
///
/// * `description` - A string slice of the description you would like to use
///
pub fn publish_own_description(&self, description: &str) -> Result<String, SbotCliError> {
let self_id = &self.whoami()?;
self.publish_description(description, self_id)
}
/// Publish a post (public message).
///
/// Calls `sbotcli publish post [text]". On success: trims the trailing whitespace from `stdout` and returns the message reference. On error: returns the `stderr` output with a description.
@ -439,7 +504,7 @@ impl Sbot {
/// Calls `sbotcli call whoami`. On success: parses the `stdout` to extract the ID and returns it.
/// On error: returns the `stderr` output with a description.
///
pub fn whoami(&self) -> Result<Option<String>, SbotCliError> {
pub fn whoami(&self) -> Result<String, SbotCliError> {
let output = Command::new(&self.sbotcli_path)
.arg("call")
.arg("whoami")
@ -447,8 +512,16 @@ impl Sbot {
if output.status.success() {
let stdout = String::from_utf8(output.stdout)?;
let id = utils::regex_finder(r#""id": "(.*)"\n"#, &stdout)?;
Ok(id)
match id {
// if the regex matches, then return the result
Some(id) => {
Ok(id)
},
// if the regex does not match, then return an error
None => {
glyph marked this conversation as resolved
Review

I'm in two minds about returning an error for the no-capture condition. It's technically not an error, since the whoami call was executed successfully and regex_finder returned Ok. This is why I originally chose to return a Result<Option<String>, SbotCliError>; a None value represents a failure to obtain the id and the caller must match accordingly.

With that being said, I think it's extremely unlikely that we fail to capture the id. That would only happen if our regex pattern were incorrect or if there was a low-level error in gosbot for the whoami method.

If we stick with the current error approach, I'd recommend making the message more specific:

"Error calling whoami: failed to capture the id value using regex"

I'm in two minds about returning an error for the no-capture condition. It's technically not an error, since the `whoami` call was executed successfully and `regex_finder` returned `Ok`. This is why I originally chose to return a `Result<Option<String>, SbotCliError>`; a `None` value represents a failure to obtain the `id` and the caller must match accordingly. With that being said, I think it's extremely unlikely that we fail to capture the `id`. That would only happen if our regex pattern were incorrect or if there was a low-level error in `gosbot` for the `whoami` method. If we stick with the current error approach, I'd recommend making the message more specific: "Error calling whoami: failed to capture the id value using regex"
Review

imo an error is technically not just when an underlying call returns an error, but whenever a function fails to do what you want it to do, however you define that.

To me it makes the most sense to define that if this function is working it returns an id, and if it doesn't then it returns an error, because I can't think of a case where sbot is working but you wouldn't have an id from whoami, and defining it in this way makes it easier for the caller to use in most use cases where the ID is really what they want.

Returning an Option feels to me like creating unnessesary work. Or is there a case where whoami should return None?

imo an error is technically not just when an underlying call returns an error, but whenever a function fails to do what you want it to do, however you define that. To me it makes the most sense to define that if this function is working it returns an id, and if it doesn't then it returns an error, because I can't think of a case where sbot is working but you wouldn't have an id from whoami, and defining it in this way makes it easier for the caller to use in most use cases where the ID is really what they want. Returning an Option feels to me like creating unnessesary work. Or is there a case where whoami should return None?
Review

Agreed that the Option will create unnecessary work for the caller and may result in confusion. Also agreed that the ID value should always be returned from the sbot if the whoami call is successful. Error approach is fine by me 👍

Clear to merge 🟢

Agreed that the `Option` will create unnecessary work for the caller and may result in confusion. Also agreed that the ID value should always be returned from the sbot if the `whoami` call is successful. Error approach is fine by me 👍 Clear to merge 🟢
Err(SbotCliError::WhoAmI("Error calling whoami: failed to capture the id value using regex".to_string()))
}
}
} else {
let stderr = std::str::from_utf8(&output.stderr)?;
Err(SbotCliError::WhoAmI(format!(