folder_rev.rs 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. use crate::{TrashRevision, WorkspaceRevision};
  2. use serde::de::{MapAccess, Visitor};
  3. use serde::{de, Deserialize, Deserializer, Serialize};
  4. use std::fmt;
  5. use std::sync::Arc;
  6. #[derive(Debug, Default, Serialize, Clone, Eq, PartialEq)]
  7. pub struct FolderRevision {
  8. pub workspaces: Vec<Arc<WorkspaceRevision>>,
  9. pub trash: Vec<Arc<TrashRevision>>,
  10. }
  11. impl<'de> Deserialize<'de> for FolderRevision {
  12. fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
  13. where
  14. D: Deserializer<'de>,
  15. {
  16. struct FolderVisitor<'a>(&'a mut Option<FolderRevision>);
  17. impl<'de, 'a> Visitor<'de> for FolderVisitor<'a> {
  18. type Value = ();
  19. fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
  20. formatter.write_str("Expect struct FolderRevision")
  21. }
  22. fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
  23. where
  24. A: MapAccess<'de>,
  25. {
  26. let mut workspaces: Option<Vec<WorkspaceRevision>> = None;
  27. let mut trash: Option<Vec<TrashRevision>> = None;
  28. while let Some(key) = map.next_key::<String>()? {
  29. if key == "workspaces" && workspaces.is_none() {
  30. workspaces = Some(map.next_value::<Vec<WorkspaceRevision>>()?);
  31. }
  32. if key == "trash" && trash.is_none() {
  33. trash = Some(map.next_value::<Vec<TrashRevision>>()?);
  34. }
  35. }
  36. if let Some(workspaces) = workspaces {
  37. *self.0 = Some(FolderRevision {
  38. workspaces: workspaces.into_iter().map(Arc::new).collect(),
  39. trash: trash
  40. .unwrap_or_default()
  41. .into_iter()
  42. .map(Arc::new)
  43. .collect(),
  44. });
  45. Ok(())
  46. } else {
  47. Err(de::Error::missing_field("workspaces"))
  48. }
  49. }
  50. }
  51. let mut folder_rev: Option<FolderRevision> = None;
  52. const FIELDS: &[&str] = &["workspaces", "trash"];
  53. let _ = serde::Deserializer::deserialize_struct(
  54. deserializer,
  55. "FolderRevision",
  56. FIELDS,
  57. FolderVisitor(&mut folder_rev),
  58. );
  59. match folder_rev {
  60. None => Err(de::Error::missing_field("workspaces or trash")),
  61. Some(folder_rev) => Ok(folder_rev),
  62. }
  63. }
  64. }