Skip to main content

xidl_parser/versioning/map/
model.rs

1//! Serializable version-map models and internal comparison surfaces.
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5use std::collections::BTreeMap;
6
7/// Stable, JSON-serializable version history facts.
8#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
9pub struct VersionMap {
10    /// Schema version. Format 2 includes source declaration identity in
11    /// direct member, operation and parameter descriptors. Tokens are opaque
12    /// and comparable only within this map, not across source revisions.
13    pub format: u32,
14    /// Contract filename supplied by the caller.
15    pub contract: String,
16    /// Declared API versions in source order.
17    pub versions: Vec<MapVersion>,
18    /// Shallow differences for every adjacent pair.
19    pub steps: Vec<MapStep>,
20}
21
22/// One declared version in a [`VersionMap`].
23#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
24pub struct MapVersion {
25    /// Enum member name.
26    pub id: String,
27    /// Wire/document value.
28    pub value: String,
29}
30
31/// One adjacent version change set.
32#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
33pub struct MapStep {
34    /// Earlier version member name.
35    pub from: String,
36    /// Later version member name.
37    pub to: String,
38    /// Changed data declarations, keyed by qualified name.
39    #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
40    pub types: BTreeMap<String, TypeChange>,
41    /// Changed operations, keyed by `Interface.operation`.
42    #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
43    pub operations: BTreeMap<String, Change>,
44}
45
46/// A changed data declaration and its direct members.
47#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
48pub struct TypeChange {
49    /// `added`, `removed`, or `changed`.
50    pub change: ChangeKind,
51    /// Declaration kind for additions and changes.
52    #[serde(skip_serializing_if = "Option::is_none")]
53    pub kind: Option<String>,
54    /// Declaration-level facts for types whose shape is not represented by
55    /// members alone (for example typedefs, natives and union switches).
56    #[serde(skip_serializing_if = "Option::is_none")]
57    pub details: Option<BTreeMap<String, Value>>,
58    /// Earlier declaration facts for a changed type.
59    #[serde(skip_serializing_if = "Option::is_none")]
60    pub from: Option<BTreeMap<String, Value>>,
61    /// Later declaration facts for a changed type.
62    #[serde(skip_serializing_if = "Option::is_none")]
63    pub to: Option<BTreeMap<String, Value>>,
64    /// Direct member facts; references are intentionally not followed here.
65    #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
66    pub members: BTreeMap<String, Change>,
67}
68
69/// One added, removed, or changed fact.
70#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
71pub struct Change {
72    /// The kind of change.
73    pub change: ChangeKind,
74    /// Earlier shallow descriptor for a changed or removed item.
75    #[serde(skip_serializing_if = "Option::is_none")]
76    pub from: Option<BTreeMap<String, Value>>,
77    /// Later shallow descriptor for a changed or added item.
78    #[serde(skip_serializing_if = "Option::is_none")]
79    pub to: Option<BTreeMap<String, Value>>,
80}
81
82/// The only change classifications emitted by the core.
83#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
84#[serde(rename_all = "lowercase")]
85pub enum ChangeKind {
86    /// The item exists only in the later version.
87    Added,
88    /// The item exists only in the earlier version.
89    Removed,
90    /// The same pairing key exists with a different shallow declaration.
91    Changed,
92}
93
94#[derive(Debug, Clone, PartialEq)]
95pub(super) struct TypeSurface {
96    pub(super) kind: String,
97    pub(super) details: BTreeMap<String, Value>,
98    pub(super) members: BTreeMap<String, BTreeMap<String, Value>>,
99}
100
101pub(super) fn type_shape(surface: &TypeSurface) -> BTreeMap<String, Value> {
102    let mut shape = BTreeMap::from([("kind".to_string(), Value::String(surface.kind.clone()))]);
103    shape.extend(
104        surface
105            .details
106            .iter()
107            .map(|(key, value)| (key.clone(), value.clone())),
108    );
109    shape
110}
111
112pub(super) type TypeParts<'a> = (
113    &'a str,
114    &'a str,
115    BTreeMap<String, Value>,
116    BTreeMap<String, BTreeMap<String, Value>>,
117);
118
119#[derive(Debug, Clone, PartialEq)]
120pub(super) struct OperationSurface {
121    pub(super) source: crate::rest_hir::HttpOperationSource,
122    pub(super) parameter_sources: crate::rest_hir::project_params::sources::ParameterSources,
123    pub(super) descriptor: BTreeMap<String, Value>,
124    pub(super) params: BTreeMap<String, BTreeMap<String, Value>>,
125}