Something went wrong. Try again.
atproto Thingiverse but good
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178use jacquard_common::deps::smol_str::{SmolStr, ToSmolStr};use jacquard_common::types::string::{Did, Handle, UriValue};use polymodel_api::space_polymodel::actor::ProfileView;use polymodel_api::space_polymodel::actor::get_session::{GetSessionOutput, SessionView};#[derive(Clone, Debug, Default, PartialEq, Eq)]pub enum SessionIdentity { /// Session not yet determined — the initial state before `getSession` /// resolves. Distinct from `Anonymous` so the UI can show a loading state /// instead of flashing signed-out chrome at users who are actually signed in. #[default] Unknown, Anonymous, Authenticated(AuthenticatedIdentity),}
#[derive(Clone, Debug, PartialEq, Eq)]pub struct AuthenticatedIdentity { pub avatar: Option<UriValue>, pub did: Did, pub handle: Handle, pub display_name: Option<SmolStr>,}
impl SessionIdentity { pub fn from_get_session(output: GetSessionOutput) -> Self { match output.value { SessionView::SessionUnauthenticated(_) => Self::Anonymous, SessionView::SessionAuthenticated(session) => { let avatar = session.profile.avatar.clone(); Self::Authenticated(AuthenticatedIdentity { avatar, did: session.did, handle: session.handle, display_name: profile_display_name(&session.profile), }) } } }}
impl AuthenticatedIdentity { pub fn label(&self) -> SmolStr { self.display_name .clone() .unwrap_or_else(|| self.handle.as_str().to_smolstr()) }}
fn profile_display_name(profile: &ProfileView) -> Option<SmolStr> { profile .display_name .as_ref() .map(|value| value.to_smolstr()) .filter(|value| !value.trim().is_empty())}
#[cfg(test)]mod tests { use super::*; use jacquard_common::types::did::Did; use polymodel_api::space_polymodel::actor::ProfileView; use polymodel_api::space_polymodel::actor::get_session::{ SessionAuthenticated, SessionUnauthenticated, }; #[test] fn unauthenticated_get_session_maps_to_anonymous() { let output = GetSessionOutput { value: SessionView::SessionUnauthenticated(Box::new(SessionUnauthenticated { authenticated: false, extra_data: None, })), extra_data: None, };
assert_eq!( SessionIdentity::from_get_session(output), SessionIdentity::Anonymous ); }
#[test] fn authenticated_get_session_maps_identity_label() { let output = GetSessionOutput { value: SessionView::SessionAuthenticated(Box::new(SessionAuthenticated { did: Did::new_owned("did:plc:alice").unwrap(), handle: Handle::new_owned("alice.test").unwrap(), profile: ProfileView { avatar: None, default_license: None, indexed_at: None, description: None, did: Did::new_owned("did:plc:alice").unwrap(), display_name: Some("Alice Maker".into()), handle: "alice.test".into(), pronouns: None, thing_count: None, extra_data: None, links: None, lists: None, printers: None, record: jacquard::Data::Null, follower_count: None, following_count: None, total_likes: None, viewer: None, }, extra_data: None, authenticated: true, })), extra_data: None, };
let identity = SessionIdentity::from_get_session(output); match identity { SessionIdentity::Authenticated(auth) => assert_eq!(auth.label(), "Alice Maker"), _ => panic!("expected authenticated identity"), } } #[test] fn authenticated_get_session_retains_avatar() { let output = GetSessionOutput { value: SessionView::SessionAuthenticated(Box::new(SessionAuthenticated { did: Did::new_owned("did:plc:bob").unwrap(), handle: Handle::new_owned("bob.test").unwrap(), profile: ProfileView { avatar: Some(UriValue::new_owned("https://cdn.example/bob.jpg").unwrap()), default_license: None, indexed_at: None, description: None, did: Did::new_owned("did:plc:bob").unwrap(), display_name: None, handle: "bob.test".into(), pronouns: None, thing_count: None, extra_data: None, links: None, lists: None, printers: None, record: jacquard::Data::Null, follower_count: None, following_count: None, total_likes: None, viewer: None, }, extra_data: None, authenticated: true, })), extra_data: None, };
match SessionIdentity::from_get_session(output) { SessionIdentity::Authenticated(identity) => { assert_eq!( identity.avatar.as_ref().map(AsRef::as_ref), Some("https://cdn.example/bob.jpg") ); } _ => panic!("expected authenticated identity"), } } #[test] fn get_session_json_decodes_unauthenticated_union_arm() { let output: GetSessionOutput = serde_json::from_str(r#"{"$type":"space.polymodel.actor.getSession#sessionUnauthenticated","authenticated":false}"#).unwrap(); assert_eq!( SessionIdentity::from_get_session(output), SessionIdentity::Anonymous ); } #[test] fn get_session_json_decodes_authenticated_union_arm() { let output: GetSessionOutput = serde_json::from_str(r#"{"$type":"space.polymodel.actor.getSession#sessionAuthenticated","authenticated":true,"did":"did:plc:alice","handle":"alice.test","profile":{"avatar":null,"description":null,"did":"did:plc:alice","displayName":"Alice Maker","handle":"alice.test","record":null}}"#).unwrap(); match SessionIdentity::from_get_session(output) { SessionIdentity::Authenticated(auth) => assert_eq!(auth.label(), "Alice Maker"), _ => panic!("expected authenticated identity"), } }}