Skip to main content

mant_protocol/
selector.rs

1//! Strong wire identities for selecting nodes in projected document views.
2
3use std::{borrow::Borrow, fmt, ops::Deref};
4
5use schemars::JsonSchema;
6use serde::{Deserialize, Serialize};
7
8/// Canonical structural address emitted for a node in a projected outline.
9#[derive(
10    Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, JsonSchema,
11)]
12#[serde(transparent)]
13pub struct NodePath(String);
14
15/// User-supplied outline selector interpreted as a path, node ID, or entry alias.
16///
17/// Resolution remains an engine concern; this wire type prevents an input
18/// selector from being confused with a canonical [`NodePath`].
19#[derive(
20    Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, JsonSchema,
21)]
22#[serde(transparent)]
23pub struct NodeSelector(#[schemars(length(min = 1, max = 512))] String);
24
25impl NodePath {
26    /// Wrap a canonical path produced by a trusted projection.
27    #[must_use]
28    pub fn new(value: impl Into<String>) -> Self {
29        Self(value.into())
30    }
31
32    /// Borrow the canonical path string.
33    #[must_use]
34    pub fn as_str(&self) -> &str {
35        &self.0
36    }
37
38    /// Consume the path and return its owned string.
39    #[must_use]
40    pub fn into_string(self) -> String {
41        self.0
42    }
43}
44
45impl From<String> for NodePath {
46    fn from(value: String) -> Self {
47        Self(value)
48    }
49}
50
51impl From<&str> for NodePath {
52    fn from(value: &str) -> Self {
53        Self(value.to_owned())
54    }
55}
56
57impl AsRef<str> for NodePath {
58    fn as_ref(&self) -> &str {
59        self.as_str()
60    }
61}
62
63impl Borrow<str> for NodePath {
64    fn borrow(&self) -> &str {
65        self.as_str()
66    }
67}
68
69impl Deref for NodePath {
70    type Target = str;
71
72    fn deref(&self) -> &Self::Target {
73        self.as_str()
74    }
75}
76
77impl fmt::Display for NodePath {
78    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
79        formatter.write_str(self.as_str())
80    }
81}
82
83impl PartialEq<str> for NodePath {
84    fn eq(&self, other: &str) -> bool {
85        self.as_str() == other
86    }
87}
88
89impl PartialEq<&str> for NodePath {
90    fn eq(&self, other: &&str) -> bool {
91        self.as_str() == *other
92    }
93}
94
95impl NodeSelector {
96    /// Wrap a user-supplied selector without resolving it.
97    #[must_use]
98    pub fn new(value: impl Into<String>) -> Self {
99        Self(value.into())
100    }
101
102    /// Borrow the selector string.
103    #[must_use]
104    pub fn as_str(&self) -> &str {
105        &self.0
106    }
107
108    /// Consume the selector and return its owned string.
109    #[must_use]
110    pub fn into_string(self) -> String {
111        self.0
112    }
113}
114
115impl From<String> for NodeSelector {
116    fn from(value: String) -> Self {
117        Self(value)
118    }
119}
120
121impl From<&str> for NodeSelector {
122    fn from(value: &str) -> Self {
123        Self(value.to_owned())
124    }
125}
126
127impl AsRef<str> for NodeSelector {
128    fn as_ref(&self) -> &str {
129        self.as_str()
130    }
131}
132
133impl Borrow<str> for NodeSelector {
134    fn borrow(&self) -> &str {
135        self.as_str()
136    }
137}
138
139impl Deref for NodeSelector {
140    type Target = str;
141
142    fn deref(&self) -> &Self::Target {
143        self.as_str()
144    }
145}
146
147impl fmt::Display for NodeSelector {
148    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
149        formatter.write_str(self.as_str())
150    }
151}
152
153impl PartialEq<str> for NodeSelector {
154    fn eq(&self, other: &str) -> bool {
155        self.as_str() == other
156    }
157}
158
159impl PartialEq<&str> for NodeSelector {
160    fn eq(&self, other: &&str) -> bool {
161        self.as_str() == *other
162    }
163}