Skip to main content

dpm_model/plan/
decode.rs

1//! Inspect the version before decoding domain fields, independent of document field order.
2
3use super::Plan;
4use serde::{Deserialize, Deserializer, de};
5
6mod value;
7use value::Buffered;
8
9impl<'de> Deserialize<'de> for Plan {
10    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
11        if !deserializer.is_human_readable() {
12            return Shape::deserialize(deserializer);
13        }
14        let buffered = Buffered::deserialize(deserializer)?;
15        if let Buffered::Map(fields) = &buffered {
16            let version = fields
17                .iter()
18                .find(|(key, _)| key == "format_version")
19                .ok_or_else(|| de::Error::missing_field("format_version"))?;
20            super::read_format_version(version.1.clone()).map_err(de::Error::custom)?;
21        }
22        Shape::deserialize(buffered).map_err(de::Error::custom)
23    }
24}
25
26// The remote derive constructs Plan itself, so missing or mistyped model fields fail compilation.
27#[derive(Deserialize)]
28#[serde(remote = "Plan", rename = "Plan", deny_unknown_fields)]
29struct Shape {
30    #[serde(deserialize_with = "super::read_format_version")]
31    format_version: u32,
32    assets: std::collections::BTreeMap<crate::AssetId, crate::WorkspaceAsset>,
33    workspace: crate::Workspace,
34    revision: u64,
35    projects: std::collections::BTreeMap<crate::ProjectId, crate::Project>,
36    work_items: std::collections::BTreeMap<crate::WorkItemId, crate::WorkItem>,
37    requirements: std::collections::BTreeMap<crate::RequirementId, crate::Requirement>,
38    artifacts: std::collections::BTreeMap<crate::ArtifactId, crate::Artifact>,
39    decisions: std::collections::BTreeMap<crate::DecisionId, crate::Decision>,
40    risks: std::collections::BTreeMap<crate::RiskId, crate::Risk>,
41    dependencies: Vec<crate::Dependency>,
42    #[serde(default)]
43    external_references:
44        std::collections::BTreeMap<crate::ExternalReferenceId, crate::ExternalReference>,
45    #[serde(default)]
46    links: Vec<crate::WorkLink>,
47    #[serde(default)]
48    calendars: Option<crate::Calendars>,
49}