A better Rust ATProto crate

fix for SessionKey lifetime nonense?

Orual 762dfc49 8306ce86

Changed files
+16 -17
crates
+4 -1
Cargo.toml
··· 33 33 serde_html_form = "0.2" 34 34 serde_ipld_dagcbor = "0.6" 35 35 serde_repr = "0.1" 36 + facet = "0.6" 37 + facet-json = "0.6" 38 + cfg-if = "1.0" 36 39 37 40 # Error handling 38 41 miette = "7.6" ··· 88 91 jose-jwk = "0.1" 89 92 90 93 # Text processing 91 - regex = { version = "1.11", default-features = false } 94 + regex = { version = "1.12", default-features = false } 92 95 webpage = { version = "2.0", default-features = false }
+1 -6
crates/jacquard-lexicon/src/codegen/structs.rs
··· 340 340 let rust_type = if is_required { 341 341 rust_type 342 342 } else { 343 - // Use std::option::Option for non-builder structs to avoid name collision 344 - if is_builder { 345 - quote! { Option<#rust_type> } 346 - } else { 347 - quote! { std::option::Option<#rust_type> } 348 - } 343 + quote! { std::option::Option<#rust_type> } 349 344 }; 350 345 351 346 // Extract description from field type
+1 -1
crates/jacquard/src/client.rs
··· 1206 1206 async move { 1207 1207 CredentialSession::<S, T, W>::session_info(self) 1208 1208 .await 1209 - .map(|(did, sid)| (did, Some(sid))) 1209 + .map(|key| (key.0, Some(key.1))) 1210 1210 } 1211 1211 } 1212 1212 fn endpoint(&self) -> impl Future<Output = CowStr<'static>> {
+6 -5
crates/jacquard/src/client/credential_session.rs
··· 30 30 use jacquard_common::xrpc::XrpcSubscription; 31 31 32 32 /// Storage key for app‑password sessions: `(account DID, session id)`. 33 - pub type SessionKey = (Did<'static>, CowStr<'static>); 33 + #[derive(Debug, Clone, PartialEq, Eq, Hash)] 34 + pub struct SessionKey(pub Did<'static>, pub CowStr<'static>); 34 35 35 36 /// Stateful client for app‑password based sessions. 36 37 /// ··· 273 274 let session = AtpSession::from(out); 274 275 275 276 let sid = session_id.unwrap_or_else(|| CowStr::new_static("session")); 276 - let key = (session.did.clone(), sid.into_static()); 277 + let key = SessionKey(session.did.clone(), sid.into_static()); 277 278 self.store 278 279 .set(key.clone(), session.clone()) 279 280 .await ··· 306 307 tracing::info_span!("credential_session_restore", did = %did, session_id = %session_id) 307 308 .entered(); 308 309 309 - let key = (did.clone().into_static(), session_id.clone().into_static()); 310 + let key = SessionKey(did.clone().into_static(), session_id.clone().into_static()); 310 311 let Some(sess) = self.store.get(&key).await else { 311 312 return Err(ClientError::auth(AuthError::NotAuthenticated)); 312 313 }; ··· 331 332 *self.endpoint.write().await = Some(pds.to_cowstr().into_static()); 332 333 // ensure store has the session (no-op if it existed) 333 334 self.store 334 - .set((sess.did.clone(), session_id.into_static()), sess) 335 + .set(SessionKey(sess.did.clone(), session_id.into_static()), sess) 335 336 .await?; 336 337 if let Some(file_store) = 337 338 (&*self.store as &dyn Any).downcast_ref::<crate::client::token::FileAuthStore>() ··· 356 357 where 357 358 S: Any + 'static, 358 359 { 359 - let key = (did.clone().into_static(), session_id.into_static()); 360 + let key = SessionKey(did.clone().into_static(), session_id.into_static()); 360 361 if self.store.get(&key).await.is_none() { 361 362 return Err(ClientError::auth(AuthError::NotAuthenticated)); 362 363 }
+1 -1
crates/jacquard/src/client/token.rs
··· 475 475 did: Did::new_static("did:plc:alice").unwrap(), 476 476 handle: Handle::new_static("alice.bsky.social").unwrap(), 477 477 }; 478 - let key: SessionKey = (session.did.clone(), "session".into()); 478 + let key = SessionKey(session.did.clone(), "session".into()); 479 479 jacquard_common::session::SessionStore::set(&store, key.clone(), session.clone()) 480 480 .await 481 481 .unwrap();
+1 -1
crates/jacquard/tests/agent.rs
··· 97 97 did: Did::new_static("did:plc:alice").unwrap(), 98 98 handle: Handle::new_static("alice.bsky.social").unwrap(), 99 99 }; 100 - let key: SessionKey = (atp.did.clone(), "session".into()); 100 + let key = SessionKey(atp.did.clone(), "session".into()); 101 101 jacquard_common::session::SessionStore::set(store.as_ref(), key.clone(), atp) 102 102 .await 103 103 .unwrap();
+1 -1
crates/jacquard/tests/credential_session.rs
··· 247 247 ); 248 248 249 249 // Verify store updated with refreshed tokens 250 - let key: SessionKey = ( 250 + let key = SessionKey( 251 251 Did::new_static("did:plc:alice").unwrap(), 252 252 jacquard::CowStr::from("session"), 253 253 );
+1 -1
crates/jacquard/tests/restore_pds_cache.rs
··· 91 91 did: Did::new_static("did:plc:alice").unwrap(), 92 92 handle: Handle::new_static("alice.bsky.social").unwrap(), 93 93 }; 94 - let key: SessionKey = (session.did.clone(), "session".into()); 94 + let key = SessionKey(session.did.clone(), "session".into()); 95 95 jacquard_common::session::SessionStore::set(store.as_ref(), key.clone(), session) 96 96 .await 97 97 .unwrap();