1use serde::{Deserialize, Serialize};
20
21use crate::validate::{Validate, ValidationIssue};
22
23#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
38#[serde(transparent)]
39pub struct PrimVec<T>(pub Vec<Option<T>>);
40
41impl<T> PrimVec<T> {
42 #[must_use]
44 pub fn new() -> Self {
45 Self(Vec::new())
46 }
47
48 #[must_use]
50 pub fn len(&self) -> usize {
51 self.0.len()
52 }
53
54 #[must_use]
56 pub fn is_empty(&self) -> bool {
57 self.0.is_empty()
58 }
59
60 pub fn values(&self) -> impl Iterator<Item = &T> {
62 self.0.iter().filter_map(Option::as_ref)
63 }
64
65 pub fn iter(&self) -> std::slice::Iter<'_, Option<T>> {
67 self.0.iter()
68 }
69
70 pub fn push(&mut self, value: T) {
72 self.0.push(Some(value));
73 }
74
75 pub fn push_placeholder(&mut self) {
78 self.0.push(None);
79 }
80
81 #[must_use]
83 pub fn first_value(&self) -> Option<&T> {
84 self.values().next()
85 }
86}
87
88impl<T> From<Vec<T>> for PrimVec<T> {
89 fn from(values: Vec<T>) -> Self {
90 Self(values.into_iter().map(Some).collect())
91 }
92}
93
94impl<T> FromIterator<T> for PrimVec<T> {
95 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
96 Self(iter.into_iter().map(Some).collect())
97 }
98}
99
100impl<T> FromIterator<Option<T>> for PrimVec<T> {
101 fn from_iter<I: IntoIterator<Item = Option<T>>>(iter: I) -> Self {
102 Self(iter.into_iter().collect())
103 }
104}
105
106impl<T> IntoIterator for PrimVec<T> {
107 type Item = Option<T>;
108 type IntoIter = std::vec::IntoIter<Option<T>>;
109 fn into_iter(self) -> Self::IntoIter {
110 self.0.into_iter()
111 }
112}
113
114impl<'a, T> IntoIterator for &'a PrimVec<T> {
115 type Item = &'a Option<T>;
116 type IntoIter = std::slice::Iter<'a, Option<T>>;
117 fn into_iter(self) -> Self::IntoIter {
118 self.0.iter()
119 }
120}
121
122impl<T: Validate> Validate for PrimVec<T> {
123 fn validate(&self) -> Vec<ValidationIssue> {
124 let mut issues = Vec::new();
125 for v in self.values() {
126 issues.extend(v.validate());
127 }
128 issues
129 }
130}
131
132#[cfg(test)]
133mod tests {
134 use super::*;
135
136 #[test]
137 fn null_positions_round_trip() {
138 let json = ::serde_json::json!(["a", null]);
140 let v: PrimVec<String> = ::serde_json::from_value(json.clone()).expect("nulls parse");
141 assert_eq!(v.len(), 2);
142 assert_eq!(v.values().collect::<Vec<_>>(), ["a"]);
143 assert_eq!(::serde_json::to_value(&v).expect("ser"), json);
144 }
145
146 #[test]
147 fn plain_arrays_are_unchanged() {
148 let json = ::serde_json::json!(["a", "b"]);
149 let v: PrimVec<String> = ::serde_json::from_value(json.clone()).expect("parse");
150 assert_eq!(v.values().count(), 2);
151 assert_eq!(::serde_json::to_value(&v).expect("ser"), json);
152 }
153
154 #[test]
155 fn construction_from_plain_values() {
156 let v: PrimVec<i32> = vec![1, 2].into();
157 assert_eq!(v.len(), 2);
158 let w: PrimVec<i32> = [1, 2].into_iter().collect();
159 assert_eq!(v, w);
160 }
161}