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