Files
notedeck/crates/enostr/src/profile.rs
William Casarin 6bf6af7f9e profile: fix crash with ProfileState defaults
Signed-off-by: William Casarin <jb55@jb55.com>
2025-07-15 14:14:50 -07:00

111 lines
2.5 KiB
Rust

use serde_json::{Map, Value};
#[derive(Debug, Clone)]
pub struct ProfileState(Value);
impl Default for ProfileState {
fn default() -> Self {
ProfileState::new(Map::default())
}
}
impl ProfileState {
pub fn new(value: Map<String, Value>) -> Self {
Self(Value::Object(value))
}
pub fn get_str(&self, name: &str) -> Option<&str> {
self.0.get(name).and_then(|v| v.as_str())
}
pub fn values_mut(&mut self) -> &mut Map<String, Value> {
self.0.as_object_mut().unwrap()
}
/// Insert or overwrite an existing value with a string
pub fn str_mut(&mut self, name: &str) -> &mut String {
let val = self
.values_mut()
.entry(name)
.or_insert(Value::String("".to_string()));
// if its not a string, make it one. this will overrwrite
// the old value, so be careful
if !val.is_string() {
*val = Value::String("".to_string());
}
match val {
Value::String(s) => s,
// SAFETY: we replace it above, so its impossible to be something
// other than a string
_ => panic!("impossible"),
}
}
pub fn value(&self) -> &Value {
&self.0
}
pub fn to_json(&self) -> String {
// SAFETY: serializing a value should be irrefutable
serde_json::to_string(self.value()).unwrap()
}
#[inline]
pub fn name(&self) -> Option<&str> {
self.get_str("name")
}
#[inline]
pub fn banner(&self) -> Option<&str> {
self.get_str("name")
}
#[inline]
pub fn display_name(&self) -> Option<&str> {
self.get_str("display_name")
}
#[inline]
pub fn lud06(&self) -> Option<&str> {
self.get_str("lud06")
}
#[inline]
pub fn nip05(&self) -> Option<&str> {
self.get_str("nip05")
}
#[inline]
pub fn lud16(&self) -> Option<&str> {
self.get_str("lud16")
}
#[inline]
pub fn about(&self) -> Option<&str> {
self.get_str("about")
}
#[inline]
pub fn picture(&self) -> Option<&str> {
self.get_str("picture")
}
#[inline]
pub fn website(&self) -> Option<&str> {
self.get_str("website")
}
pub fn from_note_contents(contents: &str) -> Self {
let json = serde_json::from_str(contents);
let data = if let Ok(Value::Object(data)) = json {
data
} else {
Map::new()
};
Self::new(data)
}
}