A better Rust ATProto crate
1

Configure Feed

Select the types of activity you want to include in your feed.

at main 2.7 kB View raw
1use jacquard_common::Bos; 2use jacquard_common::deps::smol_str::SmolStr; 3use jacquard_derive::lexicon; 4use serde::{Deserialize, Serialize}; 5extern crate alloc; 6 7#[lexicon] 8#[derive(Serialize, Deserialize, Debug, PartialEq)] 9#[serde(rename_all = "camelCase")] 10#[serde(bound( 11 serialize = "S: Serialize + Bos<str> + AsRef<str>", 12 deserialize = "S: Deserialize<'de> + Bos<str> + AsRef<str>" 13))] 14struct TestRecord<S: Bos<str> + AsRef<str> = SmolStr> { 15 text: S, 16 count: i64, 17} 18 19#[test] 20fn test_lexicon_adds_extra_data_field() { 21 let json = r#"{"text":"hello","count":42,"unknown":"field","another":123}"#; 22 23 let record: TestRecord = serde_json::from_str(json).unwrap(); 24 25 assert_eq!(AsRef::<str>::as_ref(&record.text), "hello"); 26 assert_eq!(record.count, 42); 27 28 let extra_data = record.extra_data.unwrap(); 29 assert_eq!(extra_data.len(), 2); 30 assert!(extra_data.contains_key("unknown")); 31 assert!(extra_data.contains_key("another")); 32} 33 34#[test] 35fn test_lexicon_roundtrip() { 36 use jacquard_common::types::value::Data; 37 use std::collections::BTreeMap; 38 39 let mut extra = BTreeMap::new(); 40 extra.insert( 41 "custom".into(), 42 Data::String(jacquard_common::types::string::AtprotoStr::String( 43 SmolStr::from("value"), 44 )), 45 ); 46 extra.insert("number".into(), Data::Integer(42)); 47 extra.insert( 48 "nested".into(), 49 Data::Object(jacquard_common::types::value::Object({ 50 let mut nested_map = BTreeMap::new(); 51 nested_map.insert("inner".into(), Data::Boolean(true)); 52 nested_map 53 })), 54 ); 55 56 let record = TestRecord { 57 text: SmolStr::from("test"), 58 count: 100, 59 extra_data: Some(extra), 60 }; 61 62 let json = serde_json::to_string(&record).unwrap(); 63 let parsed: TestRecord = serde_json::from_str(&json).unwrap(); 64 65 assert_eq!(record, parsed); 66 let extra_data = parsed.extra_data.unwrap(); 67 assert_eq!(extra_data.len(), 3); 68 69 // Verify the extra fields were preserved. 70 assert!(extra_data.contains_key("custom")); 71 assert!(extra_data.contains_key("number")); 72 assert!(extra_data.contains_key("nested")); 73 74 // Verify the values. 75 if let Some(Data::String(s)) = extra_data.get("custom") { 76 assert_eq!(s.as_str(), "value"); 77 } else { 78 panic!("expected custom field to be a string"); 79 } 80 81 if let Some(Data::Integer(n)) = extra_data.get("number") { 82 assert_eq!(*n, 42); 83 } else { 84 panic!("expected number field to be an integer"); 85 } 86 87 if let Some(Data::Object(obj)) = extra_data.get("nested") { 88 assert!(obj.0.contains_key("inner")); 89 } else { 90 panic!("expected nested field to be an object"); 91 } 92}