CLI app for developers prototyping atproto functionality
1
fork

Configure Feed

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

fix: use typed envelope struct for PDS getRecord response parsing

Replaces the double-parse with serde_json::Value intermediate with a
single-pass parse into GetRecordResponse struct. This eliminates the
clone() and double deserialization path.

Changes:
- Add GetRecordResponse struct with typed value field (LabelerPolicies)
and optional uri/cid fields with #[serde(default)]
- Replace serde_json::from_slice::<Value> + from_value::<LabelerPolicies>
with single serde_json::from_slice::<GetRecordResponse>
- Remove ParseRecord and MissingValue variants from FetchRecordError
- All envelope parsing errors now map to ParseEnvelope variant; serde's
error message for missing 'value' field is already human-friendly
- Update match statement to remove now-unreachable variants

All 12 snapshot tests pass without changes, confirming error messages
remain clear.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

+19 -48
+19 -48
src/commands/test/labeler/identity.rs
··· 153 153 span: Option<SourceSpan>, 154 154 } 155 155 156 + /// Typed envelope for PDS getRecord response containing the labeler record. 157 + #[derive(serde::Deserialize)] 158 + struct GetRecordResponse { 159 + /// The labeler policies record. 160 + value: LabelerPolicies, 161 + /// Optional URI of the record. 162 + #[serde(default)] 163 + #[expect(dead_code)] 164 + uri: Option<String>, 165 + /// Optional CID of the record. 166 + #[serde(default)] 167 + #[expect(dead_code)] 168 + cid: Option<String>, 169 + } 170 + 156 171 /// Typed error for labeler record fetch failures with rich diagnostics. 157 172 #[derive(Debug, Error)] 158 173 enum FetchRecordError { ··· 168 183 #[error("PDS returned HTTP {status}")] 169 184 HttpStatus { status: u16, body: Arc<[u8]> }, 170 185 171 - /// PDS response missing 'value' field. 172 - #[error("PDS response envelope missing 'value' field")] 173 - MissingValue { body: Arc<[u8]> }, 174 - 175 186 /// Failed to parse PDS getRecord envelope. 176 187 #[error("Failed to parse PDS getRecord envelope")] 177 188 ParseEnvelope { 178 - body: Arc<[u8]>, 179 - #[source] 180 - source: serde_json::Error, 181 - }, 182 - 183 - /// Failed to parse labeler record body. 184 - #[error("Failed to parse labeler record body")] 185 - ParseRecord { 186 189 body: Arc<[u8]>, 187 190 #[source] 188 191 source: serde_json::Error, ··· 824 827 FetchRecordError::HttpStatus { .. } => { 825 828 (CheckStatus::SpecViolation, e.to_string(), None, None) 826 829 } 827 - FetchRecordError::MissingValue { body } => { 828 - let src = NamedSource::new("PDS response", body.clone()); 829 - let span = SourceSpan::new(0.into(), body.len()); 830 - ( 831 - CheckStatus::SpecViolation, 832 - "PDS response envelope missing 'value' field".to_string(), 833 - Some(src), 834 - Some(span), 835 - ) 836 - } 837 830 FetchRecordError::ParseEnvelope { body, .. } => { 838 831 let src = NamedSource::new("PDS response", body.clone()); 839 832 let span = SourceSpan::new(0.into(), body.len()); 840 833 ( 841 834 CheckStatus::SpecViolation, 842 835 "Failed to parse PDS getRecord envelope".to_string(), 843 - Some(src), 844 - Some(span), 845 - ) 846 - } 847 - FetchRecordError::ParseRecord { body, .. } => { 848 - let src = NamedSource::new("labeler record", body.clone()); 849 - let span = SourceSpan::new(0.into(), body.len()); 850 - ( 851 - CheckStatus::SpecViolation, 852 - "Failed to parse labeler record body".to_string(), 853 836 Some(src), 854 837 Some(span), 855 838 ) ··· 1080 1063 match status { 1081 1064 404 => Err(FetchRecordError::NotFound), 1082 1065 200 => { 1083 - // Try to deserialize the response body into LabelerPolicies. 1084 - // The response is wrapped in {value: LabelerPolicies, uri, cid}, so extract the value field. 1085 - match serde_json::from_slice::<serde_json::Value>(body_arc.as_ref()) { 1086 - Ok(response_obj) => { 1087 - if let Some(value) = response_obj.get("value") { 1088 - match serde_json::from_value::<LabelerPolicies>(value.clone()) { 1089 - Ok(policies) => Ok((body_arc, policies)), 1090 - Err(e) => Err(FetchRecordError::ParseRecord { 1091 - body: body_arc, 1092 - source: e, 1093 - }), 1094 - } 1095 - } else { 1096 - Err(FetchRecordError::MissingValue { body: body_arc }) 1097 - } 1098 - } 1066 + // Try to deserialize the response body into the typed envelope. 1067 + // The response is expected to have {value: LabelerPolicies, uri?, cid?}. 1068 + match serde_json::from_slice::<GetRecordResponse>(body_arc.as_ref()) { 1069 + Ok(response) => Ok((body_arc, response.value)), 1099 1070 Err(e) => Err(FetchRecordError::ParseEnvelope { 1100 1071 body: body_arc, 1101 1072 source: e,