···472 Some(serde_json::Value::Array(arr)) => {
473 let mut keys = Vec::with_capacity(arr.len());
474 let mut failed = false;
475- for v in arr {
476 match v {
477- serde_json::Value::String(s) => match DidKey::from_did_key(&s) {
478 Ok(k) => keys.push(k),
479 Err(e) => {
480 errors.push(StoredOpError::InvalidField(
···496 }
497 }
498 if failed {
499- // we don't have the original array anymore here because we consumed it,
500- // but we can reconstruct it for the unknown map if we really want to,
501- // though usually we just move the whole thing.
502- // since we consumed it, let's just push an error and return None.
503- // to be absolutely correct about preserving 'unknown', we should have peeked or cloned.
504- // let's adjust the implementation to clone if we suspect it might fail,
505- // OR just move the whole value back if it fails.
506 Option::None
507 } else {
508 Some(keys)
···523 Some(serde_json::Value::Object(map)) => {
524 let mut methods = BTreeMap::new();
525 let mut failed = false;
526- for (k, v) in map {
527 match v {
528- serde_json::Value::String(s) => match DidKey::from_did_key(&s) {
529 Ok(key) => {
530- methods.insert(VerificationMethodKey::from_str(&k), key);
531 }
532 Err(e) => {
533 errors.push(StoredOpError::InvalidField(
···548 }
549 }
550 }
551- if failed { Option::None } else { Some(methods) }
00000000552 }
553 Some(v) => {
554 errors.push(StoredOpError::TypeMismatch(
···562 };
563564 let also_known_as = match obj.remove(&*StoredOpField::AlsoKnownAs) {
565- Some(serde_json::Value::Array(arr)) => Some(
566- arr.into_iter()
567- .filter_map(|v| match v {
568- serde_json::Value::String(s) => Some(Aka::from_str(&s)),
569- _ => None,
570- })
571- .collect(),
572- ),
000000000000000000573 Some(v) => {
574 errors.push(StoredOpError::TypeMismatch(
575 StoredOpField::AlsoKnownAs,
···582 };
583584 let services = match obj.remove(&*StoredOpField::Services) {
585- Some(serde_json::Value::Object(map)) => Some(
586- map.into_iter()
587- .filter_map(|(k, v)| {
00000588 let svc = StoredService {
589- r#type: ServiceType::from_str(v.get("type")?.as_str()?),
590- endpoint: ServiceEndpoint::from_str(v.get("endpoint")?.as_str()?),
591 };
592- Some((ServiceKey::from_str(&k), svc))
593- })
594- .collect(),
595- ),
0000000000000000596 Some(v) => {
597 errors.push(StoredOpError::TypeMismatch(
598 StoredOpField::Services,
···472 Some(serde_json::Value::Array(arr)) => {
473 let mut keys = Vec::with_capacity(arr.len());
474 let mut failed = false;
475+ for v in &arr {
476 match v {
477+ serde_json::Value::String(s) => match DidKey::from_did_key(s) {
478 Ok(k) => keys.push(k),
479 Err(e) => {
480 errors.push(StoredOpError::InvalidField(
···496 }
497 }
498 if failed {
499+ unknown.insert(
500+ StoredOpField::RotationKeys.to_string(),
501+ serde_json::Value::Array(arr),
502+ );
000503 Option::None
504 } else {
505 Some(keys)
···520 Some(serde_json::Value::Object(map)) => {
521 let mut methods = BTreeMap::new();
522 let mut failed = false;
523+ for (k, v) in &map {
524 match v {
525+ serde_json::Value::String(s) => match DidKey::from_did_key(s) {
526 Ok(key) => {
527+ methods.insert(VerificationMethodKey::from_str(k), key);
528 }
529 Err(e) => {
530 errors.push(StoredOpError::InvalidField(
···545 }
546 }
547 }
548+ if failed {
549+ unknown.insert(
550+ StoredOpField::VerificationMethods.to_string(),
551+ serde_json::Value::Object(map),
552+ );
553+ Option::None
554+ } else {
555+ Some(methods)
556+ }
557 }
558 Some(v) => {
559 errors.push(StoredOpError::TypeMismatch(
···567 };
568569 let also_known_as = match obj.remove(&*StoredOpField::AlsoKnownAs) {
570+ Some(serde_json::Value::Array(arr)) => {
571+ let mut akas = Vec::with_capacity(arr.len());
572+ let mut failed = false;
573+ for v in &arr {
574+ match v {
575+ serde_json::Value::String(s) => akas.push(Aka::from_str(s)),
576+ _ => {
577+ errors.push(StoredOpError::TypeMismatch(
578+ StoredOpField::AlsoKnownAs,
579+ "string inside array",
580+ ));
581+ failed = true;
582+ break;
583+ }
584+ }
585+ }
586+ if failed {
587+ unknown.insert(
588+ StoredOpField::AlsoKnownAs.to_string(),
589+ serde_json::Value::Array(arr),
590+ );
591+ Option::None
592+ } else {
593+ Some(akas)
594+ }
595+ }
596 Some(v) => {
597 errors.push(StoredOpError::TypeMismatch(
598 StoredOpField::AlsoKnownAs,
···605 };
606607 let services = match obj.remove(&*StoredOpField::Services) {
608+ Some(serde_json::Value::Object(map)) => {
609+ let mut svcs = BTreeMap::new();
610+ let mut failed = false;
611+ for (k, v) in &map {
612+ if let (Some(r#type), Some(endpoint)) = (
613+ v.get("type").and_then(|t| t.as_str()),
614+ v.get("endpoint").and_then(|e| e.as_str()),
615+ ) {
616 let svc = StoredService {
617+ r#type: ServiceType::from_str(r#type),
618+ endpoint: ServiceEndpoint::from_str(endpoint),
619 };
620+ svcs.insert(ServiceKey::from_str(k), svc);
621+ } else {
622+ errors.push(StoredOpError::TypeMismatch(
623+ StoredOpField::Services,
624+ "missing or invalid type/endpoint in service object",
625+ ));
626+ failed = true;
627+ break;
628+ }
629+ }
630+ if failed {
631+ unknown.insert(
632+ StoredOpField::Services.to_string(),
633+ serde_json::Value::Object(map),
634+ );
635+ Option::None
636+ } else {
637+ Some(svcs)
638+ }
639+ }
640 Some(v) => {
641 errors.push(StoredOpError::TypeMismatch(
642 StoredOpField::Services,