A better Rust ATProto crate

refactored out the string insertion simplified the big match statements to remove redundant code and check more conditions in the match arms

Orual b5ef4bce 31f3fb7b

Changed files
+179 -393
crates
jacquard-common
src
types
+179 -393
crates/jacquard-common/src/types/value.rs
··· 99 99 100 100 for (key, value) in json { 101 101 if key == "$type" { 102 - continue; // skip, because we've already handled it 102 + map.insert(key.to_smolstr(), Data::from_json(value)); 103 103 } 104 104 match string_key_type_guess(key) { 105 - DataModelType::Null => { 106 - if value.is_null() { 107 - map.insert(key.to_smolstr(), Data::Null); 108 - } else { 109 - map.insert(key.to_smolstr(), Data::from_json(value)); 110 - } 105 + DataModelType::Null if value.is_null() => { 106 + map.insert(key.to_smolstr(), Data::Null); 111 107 } 112 - DataModelType::Boolean => { 113 - if let Some(value) = value.as_bool() { 114 - map.insert(key.to_smolstr(), Data::Boolean(value)); 115 - } else { 116 - map.insert(key.to_smolstr(), Data::from_json(value)); 117 - } 108 + DataModelType::Boolean if value.is_boolean() => { 109 + map.insert(key.to_smolstr(), Data::Boolean(value.as_bool().unwrap())); 118 110 } 119 - DataModelType::Integer => { 120 - if let Some(int) = value.as_i64() { 121 - map.insert(key.to_smolstr(), Data::Integer(int)); 122 - } else { 123 - map.insert(key.to_smolstr(), Data::from_json(value)); 124 - } 111 + DataModelType::Integer if value.is_i64() => { 112 + map.insert(key.to_smolstr(), Data::Integer(value.as_i64().unwrap())); 125 113 } 126 - DataModelType::Bytes => { 127 - if let Some(value) = value.as_str() { 128 - map.insert(key.to_smolstr(), decode_bytes(value)); 129 - } else { 130 - map.insert(key.to_smolstr(), Data::from_json(value)); 131 - } 114 + DataModelType::Bytes if value.is_string() => { 115 + map.insert(key.to_smolstr(), decode_bytes(value.as_str().unwrap())); 132 116 } 133 117 DataModelType::CidLink => { 134 118 if let Some(value) = value.as_object() { ··· 141 125 map.insert(key.to_smolstr(), Data::from_json(value)); 142 126 } 143 127 } 144 - DataModelType::Blob => { 145 - if let Some(value) = value.as_object() { 146 - map.insert(key.to_smolstr(), Object::from_json(value)); 147 - } else { 148 - map.insert(key.to_smolstr(), Data::from_json(value)); 149 - } 128 + DataModelType::Blob if value.is_object() => { 129 + map.insert( 130 + key.to_smolstr(), 131 + Object::from_json(value.as_object().unwrap()), 132 + ); 150 133 } 151 - DataModelType::Array => { 152 - if let Some(value) = value.as_array() { 153 - map.insert(key.to_smolstr(), Data::Array(Array::from_json(value))); 154 - } else { 155 - map.insert(key.to_smolstr(), Data::from_json(value)); 156 - } 134 + DataModelType::Array if value.is_array() => { 135 + map.insert( 136 + key.to_smolstr(), 137 + Data::Array(Array::from_json(value.as_array().unwrap())), 138 + ); 157 139 } 158 - DataModelType::Object => { 159 - if let Some(value) = value.as_object() { 160 - map.insert(key.to_smolstr(), Object::from_json(value)); 161 - } else { 162 - map.insert(key.to_smolstr(), Data::from_json(value)); 163 - } 140 + DataModelType::Object if value.is_object() => { 141 + map.insert( 142 + key.to_smolstr(), 143 + Object::from_json(value.as_object().unwrap()), 144 + ); 164 145 } 165 - DataModelType::String(string_type) => { 166 - if let Some(value) = value.as_str() { 167 - match string_type { 168 - LexiconStringType::Datetime => { 169 - if let Ok(datetime) = Datetime::from_str(value) { 170 - map.insert( 171 - key.to_smolstr(), 172 - Data::String(AtprotoStr::Datetime(datetime)), 173 - ); 174 - } else { 175 - map.insert( 176 - key.to_smolstr(), 177 - Data::String(AtprotoStr::String(value.into())), 178 - ); 179 - } 180 - } 181 - LexiconStringType::AtUri => { 182 - if let Ok(value) = AtUri::new(value) { 183 - map.insert( 184 - key.to_smolstr(), 185 - Data::String(AtprotoStr::AtUri(value)), 186 - ); 187 - } else { 188 - map.insert( 189 - key.to_smolstr(), 190 - Data::String(AtprotoStr::String(value.into())), 191 - ); 192 - } 193 - } 194 - LexiconStringType::Did => { 195 - if let Ok(value) = Did::new(value) { 196 - map.insert( 197 - key.to_smolstr(), 198 - Data::String(AtprotoStr::Did(value)), 199 - ); 200 - } else { 201 - map.insert( 202 - key.to_smolstr(), 203 - Data::String(AtprotoStr::String(value.into())), 204 - ); 205 - } 206 - } 207 - LexiconStringType::Handle => { 208 - if let Ok(value) = Handle::new(value) { 209 - map.insert( 210 - key.to_smolstr(), 211 - Data::String(AtprotoStr::Handle(value)), 212 - ); 213 - } else { 214 - map.insert( 215 - key.to_smolstr(), 216 - Data::String(AtprotoStr::String(value.into())), 217 - ); 218 - } 219 - } 220 - LexiconStringType::AtIdentifier => { 221 - if let Ok(value) = AtIdentifier::new(value) { 222 - map.insert( 223 - key.to_smolstr(), 224 - Data::String(AtprotoStr::AtIdentifier(value)), 225 - ); 226 - } else { 227 - map.insert( 228 - key.to_smolstr(), 229 - Data::String(AtprotoStr::String(value.into())), 230 - ); 231 - } 232 - } 233 - LexiconStringType::Nsid => { 234 - if let Ok(value) = Nsid::new(value) { 235 - map.insert( 236 - key.to_smolstr(), 237 - Data::String(AtprotoStr::Nsid(value)), 238 - ); 239 - } else { 240 - map.insert( 241 - key.to_smolstr(), 242 - Data::String(AtprotoStr::String(value.into())), 243 - ); 244 - } 245 - } 246 - LexiconStringType::Cid => { 247 - if let Ok(value) = Cid::new(value.as_bytes()) { 248 - map.insert( 249 - key.to_smolstr(), 250 - Data::String(AtprotoStr::Cid(value)), 251 - ); 252 - } else { 253 - map.insert( 254 - key.to_smolstr(), 255 - Data::String(AtprotoStr::String(value.into())), 256 - ); 257 - } 258 - } 259 - LexiconStringType::Language => { 260 - if let Ok(value) = Language::new(value) { 261 - map.insert( 262 - key.to_smolstr(), 263 - Data::String(AtprotoStr::Language(value)), 264 - ); 265 - } else { 266 - map.insert( 267 - key.to_smolstr(), 268 - Data::String(AtprotoStr::String(value.into())), 269 - ); 270 - } 271 - } 272 - LexiconStringType::Tid => { 273 - if let Ok(value) = Tid::new(value) { 274 - map.insert( 275 - key.to_smolstr(), 276 - Data::String(AtprotoStr::Tid(value)), 277 - ); 278 - } else { 279 - map.insert( 280 - key.to_smolstr(), 281 - Data::String(AtprotoStr::String(value.into())), 282 - ); 283 - } 284 - } 285 - LexiconStringType::RecordKey => { 286 - if let Ok(value) = Rkey::new(value) { 287 - map.insert( 288 - key.to_smolstr(), 289 - Data::String(AtprotoStr::RecordKey(RecordKey::from(value))), 290 - ); 291 - } else { 292 - map.insert( 293 - key.to_smolstr(), 294 - Data::String(AtprotoStr::String(value.into())), 295 - ); 296 - } 297 - } 298 - LexiconStringType::Uri(_) => { 299 - if let Ok(uri) = Uri::new(value) { 300 - map.insert( 301 - key.to_smolstr(), 302 - Data::String(AtprotoStr::Uri(uri)), 303 - ); 304 - } else { 305 - map.insert( 306 - key.to_smolstr(), 307 - Data::String(AtprotoStr::String(value.into())), 308 - ); 309 - } 310 - } 311 - LexiconStringType::String => { 312 - map.insert(key.to_smolstr(), Data::String(parse_string(value))); 313 - } 314 - } 315 - } else { 316 - map.insert(key.to_smolstr(), Data::from_json(value)); 317 - } 146 + DataModelType::String(string_type) if value.is_string() => { 147 + insert_string(&mut map, key, value.as_str().unwrap(), string_type); 148 + } 149 + _ => { 150 + map.insert(key.to_smolstr(), Data::from_json(value)); 318 151 } 319 152 } 320 153 } ··· 334 167 335 168 for (key, value) in cbor { 336 169 if key == "$type" { 337 - continue; // skip, because we've already handled it 170 + map.insert(key.to_smolstr(), Data::from_cbor(value)); 338 171 } 339 - match string_key_type_guess(key) { 340 - DataModelType::Null => { 341 - if *value == Ipld::Null { 342 - map.insert(key.to_smolstr(), Data::Null); 343 - } else { 344 - map.insert(key.to_smolstr(), Data::from_cbor(value)); 345 - } 172 + match (string_key_type_guess(key), value) { 173 + (DataModelType::Null, Ipld::Null) => { 174 + map.insert(key.to_smolstr(), Data::Null); 346 175 } 347 - DataModelType::Boolean => { 348 - if let Ipld::Bool(value) = value { 349 - map.insert(key.to_smolstr(), Data::Boolean(*value)); 350 - } else { 351 - map.insert(key.to_smolstr(), Data::from_cbor(value)); 352 - } 176 + (DataModelType::Boolean, Ipld::Bool(value)) => { 177 + map.insert(key.to_smolstr(), Data::Boolean(*value)); 353 178 } 354 - DataModelType::Integer => { 355 - if let Ipld::Integer(int) = value { 356 - map.insert(key.to_smolstr(), Data::Integer(*int as i64)); 357 - } else { 358 - map.insert(key.to_smolstr(), Data::from_cbor(value)); 359 - } 179 + (DataModelType::Integer, Ipld::Integer(int)) => { 180 + map.insert(key.to_smolstr(), Data::Integer(*int as i64)); 360 181 } 361 - DataModelType::Bytes => { 362 - if let Ipld::Bytes(value) = value { 363 - map.insert(key.to_smolstr(), Data::Bytes(Bytes::copy_from_slice(value))); 364 - } else { 365 - map.insert(key.to_smolstr(), Data::from_cbor(value)); 366 - } 182 + (DataModelType::Bytes, Ipld::Bytes(value)) => { 183 + map.insert(key.to_smolstr(), Data::Bytes(Bytes::copy_from_slice(value))); 367 184 } 368 - DataModelType::Blob => { 369 - if let Ipld::Map(value) = value { 370 - map.insert(key.to_smolstr(), Object::from_cbor(value)); 371 - } else { 372 - map.insert(key.to_smolstr(), Data::from_cbor(value)); 373 - } 185 + (DataModelType::Blob, Ipld::Map(value)) => { 186 + map.insert(key.to_smolstr(), Object::from_cbor(value)); 374 187 } 375 - DataModelType::Array => { 376 - if let Ipld::List(value) = value { 377 - map.insert(key.to_smolstr(), Data::Array(Array::from_cbor(value))); 378 - } else { 379 - map.insert(key.to_smolstr(), Data::from_cbor(value)); 380 - } 188 + (DataModelType::Array, Ipld::List(value)) => { 189 + map.insert(key.to_smolstr(), Data::Array(Array::from_cbor(value))); 381 190 } 382 - DataModelType::Object => { 383 - if let Ipld::Map(value) = value { 384 - map.insert(key.to_smolstr(), Object::from_cbor(value)); 385 - } else { 386 - map.insert(key.to_smolstr(), Data::from_cbor(value)); 387 - } 191 + (DataModelType::Object, Ipld::Map(value)) => { 192 + map.insert(key.to_smolstr(), Object::from_cbor(value)); 388 193 } 389 - DataModelType::String(string_type) => { 390 - if let Ipld::String(value) = value { 391 - match string_type { 392 - LexiconStringType::Datetime => { 393 - if let Ok(datetime) = Datetime::from_str(value) { 394 - map.insert( 395 - key.to_smolstr(), 396 - Data::String(AtprotoStr::Datetime(datetime)), 397 - ); 398 - } else { 399 - map.insert( 400 - key.to_smolstr(), 401 - Data::String(AtprotoStr::String(value.into())), 402 - ); 403 - } 404 - } 405 - LexiconStringType::AtUri => { 406 - if let Ok(value) = AtUri::new(value) { 407 - map.insert( 408 - key.to_smolstr(), 409 - Data::String(AtprotoStr::AtUri(value)), 410 - ); 411 - } else { 412 - map.insert( 413 - key.to_smolstr(), 414 - Data::String(AtprotoStr::String(value.into())), 415 - ); 416 - } 417 - } 418 - LexiconStringType::Did => { 419 - if let Ok(value) = Did::new(value) { 420 - map.insert( 421 - key.to_smolstr(), 422 - Data::String(AtprotoStr::Did(value)), 423 - ); 424 - } else { 425 - map.insert( 426 - key.to_smolstr(), 427 - Data::String(AtprotoStr::String(value.into())), 428 - ); 429 - } 430 - } 431 - LexiconStringType::Handle => { 432 - if let Ok(value) = Handle::new(value) { 433 - map.insert( 434 - key.to_smolstr(), 435 - Data::String(AtprotoStr::Handle(value)), 436 - ); 437 - } else { 438 - map.insert( 439 - key.to_smolstr(), 440 - Data::String(AtprotoStr::String(value.into())), 441 - ); 442 - } 443 - } 444 - LexiconStringType::AtIdentifier => { 445 - if let Ok(value) = AtIdentifier::new(value) { 446 - map.insert( 447 - key.to_smolstr(), 448 - Data::String(AtprotoStr::AtIdentifier(value)), 449 - ); 450 - } else { 451 - map.insert( 452 - key.to_smolstr(), 453 - Data::String(AtprotoStr::String(value.into())), 454 - ); 455 - } 456 - } 457 - LexiconStringType::Nsid => { 458 - if let Ok(value) = Nsid::new(value) { 459 - map.insert( 460 - key.to_smolstr(), 461 - Data::String(AtprotoStr::Nsid(value)), 462 - ); 463 - } else { 464 - map.insert( 465 - key.to_smolstr(), 466 - Data::String(AtprotoStr::String(value.into())), 467 - ); 468 - } 469 - } 470 - LexiconStringType::Cid => { 471 - if let Ok(value) = Cid::new(value.as_bytes()) { 472 - map.insert( 473 - key.to_smolstr(), 474 - Data::String(AtprotoStr::Cid(value)), 475 - ); 476 - } else { 477 - map.insert( 478 - key.to_smolstr(), 479 - Data::String(AtprotoStr::String(value.into())), 480 - ); 481 - } 482 - } 483 - LexiconStringType::Language => { 484 - if let Ok(value) = Language::new(value) { 485 - map.insert( 486 - key.to_smolstr(), 487 - Data::String(AtprotoStr::Language(value)), 488 - ); 489 - } else { 490 - map.insert( 491 - key.to_smolstr(), 492 - Data::String(AtprotoStr::String(value.into())), 493 - ); 494 - } 495 - } 496 - LexiconStringType::Tid => { 497 - if let Ok(value) = Tid::new(value) { 498 - map.insert( 499 - key.to_smolstr(), 500 - Data::String(AtprotoStr::Tid(value)), 501 - ); 502 - } else { 503 - map.insert( 504 - key.to_smolstr(), 505 - Data::String(AtprotoStr::String(value.into())), 506 - ); 507 - } 508 - } 509 - LexiconStringType::RecordKey => { 510 - if let Ok(value) = Rkey::new(value) { 511 - map.insert( 512 - key.to_smolstr(), 513 - Data::String(AtprotoStr::RecordKey(RecordKey::from(value))), 514 - ); 515 - } else { 516 - map.insert( 517 - key.to_smolstr(), 518 - Data::String(AtprotoStr::String(value.into())), 519 - ); 520 - } 521 - } 522 - LexiconStringType::Uri(_) => { 523 - if let Ok(uri) = Uri::new(value) { 524 - map.insert( 525 - key.to_smolstr(), 526 - Data::String(AtprotoStr::Uri(uri)), 527 - ); 528 - } else { 529 - map.insert( 530 - key.to_smolstr(), 531 - Data::String(AtprotoStr::String(value.into())), 532 - ); 533 - } 534 - } 535 - LexiconStringType::String => { 536 - map.insert(key.to_smolstr(), Data::String(parse_string(value))); 537 - } 538 - } 539 - } else { 540 - map.insert(key.to_smolstr(), Data::from_cbor(value)); 541 - } 194 + (DataModelType::String(string_type), Ipld::String(value)) => { 195 + insert_string(&mut map, key, value, string_type); 542 196 } 543 197 _ => { 544 198 map.insert(key.to_smolstr(), Data::from_cbor(value)); ··· 547 201 } 548 202 549 203 Data::Object(Object(map)) 204 + } 205 + } 206 + 207 + pub fn insert_string<'s>( 208 + map: &mut BTreeMap<SmolStr, Data<'s>>, 209 + key: &'s str, 210 + value: &'s str, 211 + string_type: LexiconStringType, 212 + ) { 213 + match string_type { 214 + LexiconStringType::Datetime => { 215 + if let Ok(datetime) = Datetime::from_str(value) { 216 + map.insert( 217 + key.to_smolstr(), 218 + Data::String(AtprotoStr::Datetime(datetime)), 219 + ); 220 + } else { 221 + map.insert( 222 + key.to_smolstr(), 223 + Data::String(AtprotoStr::String(value.into())), 224 + ); 225 + } 226 + } 227 + LexiconStringType::AtUri => { 228 + if let Ok(value) = AtUri::new(value) { 229 + map.insert(key.to_smolstr(), Data::String(AtprotoStr::AtUri(value))); 230 + } else { 231 + map.insert( 232 + key.to_smolstr(), 233 + Data::String(AtprotoStr::String(value.into())), 234 + ); 235 + } 236 + } 237 + LexiconStringType::Did => { 238 + if let Ok(value) = Did::new(value) { 239 + map.insert(key.to_smolstr(), Data::String(AtprotoStr::Did(value))); 240 + } else { 241 + map.insert( 242 + key.to_smolstr(), 243 + Data::String(AtprotoStr::String(value.into())), 244 + ); 245 + } 246 + } 247 + LexiconStringType::Handle => { 248 + if let Ok(value) = Handle::new(value) { 249 + map.insert(key.to_smolstr(), Data::String(AtprotoStr::Handle(value))); 250 + } else { 251 + map.insert( 252 + key.to_smolstr(), 253 + Data::String(AtprotoStr::String(value.into())), 254 + ); 255 + } 256 + } 257 + LexiconStringType::AtIdentifier => { 258 + if let Ok(value) = AtIdentifier::new(value) { 259 + map.insert( 260 + key.to_smolstr(), 261 + Data::String(AtprotoStr::AtIdentifier(value)), 262 + ); 263 + } else { 264 + map.insert( 265 + key.to_smolstr(), 266 + Data::String(AtprotoStr::String(value.into())), 267 + ); 268 + } 269 + } 270 + LexiconStringType::Nsid => { 271 + if let Ok(value) = Nsid::new(value) { 272 + map.insert(key.to_smolstr(), Data::String(AtprotoStr::Nsid(value))); 273 + } else { 274 + map.insert( 275 + key.to_smolstr(), 276 + Data::String(AtprotoStr::String(value.into())), 277 + ); 278 + } 279 + } 280 + LexiconStringType::Cid => { 281 + if let Ok(value) = Cid::new(value.as_bytes()) { 282 + map.insert(key.to_smolstr(), Data::String(AtprotoStr::Cid(value))); 283 + } else { 284 + map.insert( 285 + key.to_smolstr(), 286 + Data::String(AtprotoStr::String(value.into())), 287 + ); 288 + } 289 + } 290 + LexiconStringType::Language => { 291 + if let Ok(value) = Language::new(value) { 292 + map.insert(key.to_smolstr(), Data::String(AtprotoStr::Language(value))); 293 + } else { 294 + map.insert( 295 + key.to_smolstr(), 296 + Data::String(AtprotoStr::String(value.into())), 297 + ); 298 + } 299 + } 300 + LexiconStringType::Tid => { 301 + if let Ok(value) = Tid::new(value) { 302 + map.insert(key.to_smolstr(), Data::String(AtprotoStr::Tid(value))); 303 + } else { 304 + map.insert( 305 + key.to_smolstr(), 306 + Data::String(AtprotoStr::String(value.into())), 307 + ); 308 + } 309 + } 310 + LexiconStringType::RecordKey => { 311 + if let Ok(value) = Rkey::new(value) { 312 + map.insert( 313 + key.to_smolstr(), 314 + Data::String(AtprotoStr::RecordKey(RecordKey::from(value))), 315 + ); 316 + } else { 317 + map.insert( 318 + key.to_smolstr(), 319 + Data::String(AtprotoStr::String(value.into())), 320 + ); 321 + } 322 + } 323 + LexiconStringType::Uri(_) => { 324 + if let Ok(uri) = Uri::new(value) { 325 + map.insert(key.to_smolstr(), Data::String(AtprotoStr::Uri(uri))); 326 + } else { 327 + map.insert( 328 + key.to_smolstr(), 329 + Data::String(AtprotoStr::String(value.into())), 330 + ); 331 + } 332 + } 333 + LexiconStringType::String => { 334 + map.insert(key.to_smolstr(), Data::String(parse_string(value))); 335 + } 550 336 } 551 337 } 552 338