Skip to main content

rydantic/
borrowed.rs

1use crate::{
2    rules::Rules, AsyncCheck, Context, LengthType, SchemaContext, SchemaMode, SchemaReport, Stage,
3    StringType, TypeKind, ValidationError, ValidationErrors, Value,
4};
5use serde::de::{self, Visitor};
6use serde_json::{json, value::RawValue};
7use std::{
8    borrow::Cow,
9    collections::{BTreeMap, HashMap, HashSet},
10    fmt,
11    hash::BuildHasher,
12    marker::PhantomData,
13};
14
15/// A JSON subtree that can retain references into the original input buffer.
16#[derive(Debug, Clone)]
17pub enum Input<'de> {
18    Borrowed(&'de RawValue),
19    Owned(Value),
20    Object(BTreeMap<String, Input<'de>>),
21}
22impl<'de> Input<'de> {
23    pub fn into_value(self, ctx: &mut Context) -> Option<Value> {
24        match self {
25            Self::Object(object) => Self::from_object(object, ctx),
26            Self::Owned(value) => Some(value),
27            Self::Borrowed(raw) => serde_json::from_str(raw.get())
28                .map_err(|e| ctx.push(json_error(e)))
29                .ok(),
30        }
31    }
32    pub fn object(self, ctx: &mut Context) -> Option<BTreeMap<String, Self>> {
33        match self {
34            Self::Object(object) => Some(object),
35            Self::Borrowed(raw) => {
36                serde_json::from_str::<BTreeMap<String, &'de RawValue>>(raw.get())
37                    .map(|map| {
38                        map.into_iter()
39                            .map(|(k, v)| (k, Self::Borrowed(v)))
40                            .collect()
41                    })
42                    .map_err(|_| ctx.push(type_error("object")))
43                    .ok()
44            }
45            Self::Owned(Value::Object(map)) => {
46                Some(map.into_iter().map(|(k, v)| (k, Self::Owned(v))).collect())
47            }
48            _ => {
49                ctx.push(type_error("object"));
50                None
51            }
52        }
53    }
54    pub fn array(self, ctx: &mut Context) -> Option<Vec<Self>> {
55        match self {
56            Self::Borrowed(raw) => serde_json::from_str::<Vec<&'de RawValue>>(raw.get())
57                .map(|items| items.into_iter().map(Self::Borrowed).collect())
58                .map_err(|_| ctx.push(type_error("array")))
59                .ok(),
60            Self::Owned(Value::Array(items)) => Some(items.into_iter().map(Self::Owned).collect()),
61            _ => {
62                ctx.push(type_error("array"));
63                None
64            }
65        }
66    }
67    pub fn from_object(object: BTreeMap<String, Self>, ctx: &mut Context) -> Option<Value> {
68        let mut result = serde_json::Map::new();
69        for (key, value) in object {
70            result.insert(key, value.into_value(ctx)?);
71        }
72        Some(Value::Object(result))
73    }
74    pub fn is_null(&self) -> bool {
75        match self {
76            Self::Borrowed(raw) => raw.get() == "null",
77            Self::Owned(v) => v.is_null(),
78            Self::Object(_) => false,
79        }
80    }
81}
82pub(crate) fn json_error(error: serde_json::Error) -> ValidationError {
83    ValidationError::new("json_invalid", error.to_string())
84        .with_stage(Stage::Parse)
85        .with_param("line", error.line())
86        .with_param("column", error.column())
87}
88fn type_error(expected: &str) -> ValidationError {
89    ValidationError::new("type_error", format!("expected {expected}")).with_stage(Stage::Parse)
90}
91
92/// Lifetime-aware counterpart of `JsonType`. Borrowing models use this extension point.
93pub trait BorrowType<'de>: Sized {
94    fn decode(value: Input<'de>, ctx: &mut Context, coerce: bool) -> Option<Self>;
95    fn encode(&self, ctx: &mut Context) -> Value;
96    fn encode_input(&self, ctx: &mut Context) -> Value {
97        self.encode(ctx)
98    }
99    fn schema(ctx: &mut SchemaContext, coerce: bool) -> Value;
100    fn validate_into(&self, _ctx: &mut Context) {}
101    fn prepare_default(self, ctx: &mut Context) -> Option<Self> {
102        self.validate_into(ctx);
103        Some(self)
104    }
105    fn normalize(self, rules: &Rules, ctx: &mut Context) -> Option<Self> {
106        if !rules.normalizes() {
107            return Some(self);
108        }
109        let mut value = self.encode_input(ctx);
110        rules.prepare(&mut value);
111        Self::decode(Input::Owned(value), ctx, false)
112    }
113    fn validate_rules(&self, rules: &Rules, ctx: &mut Context) {
114        rules.validate(&self.encode(ctx), ctx);
115    }
116    fn missing() -> Option<Self> {
117        None
118    }
119    fn allows_missing() -> bool {
120        false
121    }
122    fn kind() -> TypeKind {
123        TypeKind::Any
124    }
125    fn async_required(_seen: &mut HashSet<&'static str>) -> bool {
126        false
127    }
128}
129
130/// Parsing API for a model containing references or `Cow` values.
131pub trait BorrowModel<'de>: BorrowType<'de> {
132    fn parse_json(input: &'de str) -> Result<Self, ValidationErrors> {
133        let raw = serde_json::from_str::<&'de RawValue>(input).map_err(json_error)?;
134        Self::parse_raw(raw)
135    }
136    fn parse_slice(input: &'de [u8]) -> Result<Self, ValidationErrors> {
137        let raw = serde_json::from_slice::<&'de RawValue>(input).map_err(json_error)?;
138        Self::parse_raw(raw)
139    }
140    fn parse_raw(raw: &'de RawValue) -> Result<Self, ValidationErrors> {
141        crate::asynchronous::sync_guard(Self::async_required(&mut HashSet::new()))?;
142        let mut ctx = Context::new();
143        let value = Self::decode(Input::Borrowed(raw), &mut ctx, false);
144        ctx.finish(value)
145    }
146    fn validate(&self) -> Result<(), ValidationErrors> {
147        crate::asynchronous::sync_guard(Self::async_required(&mut HashSet::new()))?;
148        let mut ctx = Context::new();
149        self.validate_into(&mut ctx);
150        ctx.result()
151    }
152    fn dump(&self) -> Result<Value, ValidationErrors> {
153        self.validate()?;
154        let mut ctx = Context::new();
155        let value = self.encode(&mut ctx);
156        ctx.finish(Some(value))
157    }
158    fn dump_json(&self) -> Result<String, ValidationErrors> {
159        Ok(self.dump()?.to_string())
160    }
161    fn json_schema(mode: SchemaMode) -> Value {
162        let mut ctx = SchemaContext::new(mode);
163        let root = Self::schema(&mut ctx, false);
164        ctx.finish(root)
165    }
166    fn schema_report(mode: SchemaMode) -> SchemaReport {
167        SchemaReport::new(Self::json_schema(mode))
168    }
169    fn parse_validated_json(
170        input: &'de str,
171    ) -> Result<BorrowValidated<'de, Self>, ValidationErrors> {
172        Self::parse_json(input).map(|value| BorrowValidated(value, PhantomData))
173    }
174    fn parse_json_async(
175        input: &'de str,
176    ) -> impl std::future::Future<Output = Result<Self, ValidationErrors>> + Send
177    where
178        Self: AsyncCheck + Send,
179    {
180        async move {
181            let raw = serde_json::from_str::<&'de RawValue>(input).map_err(json_error)?;
182            let mut ctx = Context::new();
183            let value = Self::decode(Input::Borrowed(raw), &mut ctx, false);
184            let value = ctx.finish(value)?;
185            let mut ctx = Context::new();
186            value.check_async(&mut ctx).await;
187            ctx.result()?;
188            Ok(value)
189        }
190    }
191    fn validate_async(
192        &self,
193    ) -> impl std::future::Future<Output = Result<(), ValidationErrors>> + Send
194    where
195        Self: AsyncCheck,
196    {
197        async move {
198            let mut ctx = Context::new();
199            self.validate_into(&mut ctx);
200            ctx.result()?;
201            let mut ctx = Context::new();
202            self.check_async(&mut ctx).await;
203            ctx.result()
204        }
205    }
206    fn dump_async(
207        &self,
208    ) -> impl std::future::Future<Output = Result<Value, ValidationErrors>> + Send
209    where
210        Self: AsyncCheck,
211    {
212        async move {
213            self.validate_async().await?;
214            let mut ctx = Context::new();
215            let value = self.encode(&mut ctx);
216            ctx.finish(Some(value))
217        }
218    }
219    fn dump_json_async(
220        &self,
221    ) -> impl std::future::Future<Output = Result<String, ValidationErrors>> + Send
222    where
223        Self: AsyncCheck,
224    {
225        async move { Ok(self.dump_async().await?.to_string()) }
226    }
227}
228#[derive(Debug, Clone, PartialEq, Eq)]
229pub struct BorrowValidated<'de, T: BorrowModel<'de>>(T, PhantomData<&'de str>);
230impl<'de, T: BorrowModel<'de>> BorrowValidated<'de, T> {
231    pub fn new(value: T) -> Result<Self, ValidationErrors> {
232        value.validate()?;
233        Ok(Self(value, PhantomData))
234    }
235    pub fn get(&self) -> &T {
236        &self.0
237    }
238    pub fn into_inner(self) -> T {
239        self.0
240    }
241}
242impl<'de, T: BorrowModel<'de>> std::ops::Deref for BorrowValidated<'de, T> {
243    type Target = T;
244    fn deref(&self) -> &T {
245        &self.0
246    }
247}
248impl<'de, T: BorrowModel<'de>> serde::Serialize for BorrowValidated<'de, T> {
249    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
250        self.0
251            .dump()
252            .map_err(serde::ser::Error::custom)?
253            .serialize(s)
254    }
255}
256
257impl<'de, T: BorrowModel<'de>> serde::Deserialize<'de> for BorrowValidated<'de, T> {
258    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
259        let raw = <&'de RawValue as serde::Deserialize>::deserialize(deserializer)?;
260        T::parse_raw(raw)
261            .map(|value| Self(value, PhantomData))
262            .map_err(serde::de::Error::custom)
263    }
264}
265
266macro_rules! owned {
267    ($($ty:ty),* $(,)?) => {$(impl<'de> BorrowType<'de> for $ty {
268        fn decode(value:Input<'de>,ctx:&mut Context,coerce:bool)->Option<Self>{<Self as crate::JsonType>::decode_input(value,ctx,coerce)}
269        fn encode(&self,ctx:&mut Context)->Value{<Self as crate::JsonType>::encode(self,ctx)}
270        fn schema(ctx:&mut SchemaContext,coerce:bool)->Value{<Self as crate::JsonType>::schema(ctx,coerce)}
271        fn validate_into(&self,ctx:&mut Context){<Self as crate::JsonType>::validate_into(self,ctx)}
272        fn validate_rules(&self,rules:&Rules,ctx:&mut Context){<Self as crate::JsonType>::validate_rules(self,rules,ctx)}
273        fn kind()->TypeKind{<Self as crate::JsonType>::kind()}
274    })*};
275}
276owned!(
277    String,
278    bool,
279    i8,
280    i16,
281    i32,
282    i64,
283    i128,
284    isize,
285    u8,
286    u16,
287    u32,
288    u64,
289    u128,
290    usize,
291    f32,
292    f64,
293    Value,
294    ()
295);
296#[cfg(feature = "chrono")]
297owned!(
298    chrono::NaiveDate,
299    chrono::NaiveTime,
300    chrono::NaiveDateTime,
301    chrono::DateTime<chrono::Utc>,
302    chrono::DateTime<chrono::FixedOffset>
303);
304#[cfg(feature = "decimal")]
305owned!(rust_decimal::Decimal);
306
307impl<'de: 'a, 'a> BorrowType<'de> for &'a str {
308    fn decode(value: Input<'de>, ctx: &mut Context, _: bool) -> Option<Self> {
309        match value {
310            Input::Borrowed(raw) => serde_json::from_str::<&'de str>(raw.get())
311                .map_err(|_| {
312                    ctx.push(
313                        ValidationError::new(
314                            "borrowed_string",
315                            "expected an unescaped JSON string; use Cow<str> for escaped strings",
316                        )
317                        .with_stage(Stage::Parse),
318                    )
319                })
320                .ok(),
321            _ => {
322                ctx.push(
323                    ValidationError::new(
324                        "borrowed_string",
325                        "a borrowed string requires input backed by the original buffer",
326                    )
327                    .with_stage(Stage::Parse),
328                );
329                None
330            }
331        }
332    }
333    fn encode(&self, _: &mut Context) -> Value {
334        Value::String((*self).to_owned())
335    }
336    fn schema(ctx: &mut SchemaContext, _: bool) -> Value {
337        if ctx.mode == SchemaMode::Input {
338            json!({"type":"string","x-rydantic-local-rules":["borrowed_unescaped_string"]})
339        } else {
340            json!({"type":"string"})
341        }
342    }
343    fn normalize(self, rules: &Rules, ctx: &mut Context) -> Option<Self> {
344        let text = if rules.trim { self.trim() } else { self };
345        if (rules.lowercase && text.to_lowercase() != text)
346            || (rules.uppercase && text.to_uppercase() != text)
347        {
348            ctx.push(ValidationError::new(
349                "borrowed_transform",
350                "case conversion requires Cow<str> or String",
351            ));
352            None
353        } else {
354            Some(text)
355        }
356    }
357    fn kind() -> TypeKind {
358        TypeKind::String
359    }
360}
361impl StringType for &str {}
362impl LengthType for &str {}
363struct CowVisitor;
364impl<'de> Visitor<'de> for CowVisitor {
365    type Value = Cow<'de, str>;
366    fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
367        f.write_str("a JSON string")
368    }
369    fn visit_borrowed_str<E: de::Error>(self, v: &'de str) -> Result<Self::Value, E> {
370        Ok(Cow::Borrowed(v))
371    }
372    fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
373        Ok(Cow::Owned(v.to_owned()))
374    }
375    fn visit_string<E: de::Error>(self, v: String) -> Result<Self::Value, E> {
376        Ok(Cow::Owned(v))
377    }
378}
379impl<'de: 'a, 'a> BorrowType<'de> for Cow<'a, str> {
380    fn decode(value: Input<'de>, ctx: &mut Context, coerce: bool) -> Option<Self> {
381        match value {
382            Input::Borrowed(raw) if raw.get().starts_with('"') => {
383                let mut deserializer = serde_json::Deserializer::from_str(raw.get());
384                serde::Deserializer::deserialize_str(&mut deserializer, CowVisitor)
385                    .map_err(|e| ctx.push(json_error(e)))
386                    .ok()
387            }
388            value => <String as BorrowType>::decode(value, ctx, coerce).map(Cow::Owned),
389        }
390    }
391    fn encode(&self, _: &mut Context) -> Value {
392        Value::String(self.to_string())
393    }
394    fn schema(ctx: &mut SchemaContext, coerce: bool) -> Value {
395        <String as crate::JsonType>::schema(ctx, coerce)
396    }
397    fn normalize(self, rules: &Rules, _: &mut Context) -> Option<Self> {
398        let value = match self {
399            Cow::Borrowed(v) => Cow::Borrowed(if rules.trim { v.trim() } else { v }),
400            Cow::Owned(v) => Cow::Owned(if rules.trim { v.trim().to_owned() } else { v }),
401        };
402        if rules.lowercase {
403            let v = value.to_lowercase();
404            if v != value {
405                return Some(Cow::Owned(v));
406            }
407        }
408        if rules.uppercase {
409            let v = value.to_uppercase();
410            if v != value {
411                return Some(Cow::Owned(v));
412            }
413        }
414        Some(value)
415    }
416    fn kind() -> TypeKind {
417        TypeKind::String
418    }
419}
420impl StringType for Cow<'_, str> {}
421impl LengthType for Cow<'_, str> {}
422
423impl<'de, T: BorrowType<'de>> BorrowType<'de> for Option<T> {
424    fn prepare_default(self, ctx: &mut Context) -> Option<Self> {
425        match self {
426            Some(value) => value.prepare_default(ctx).map(Some),
427            None => Some(None),
428        }
429    }
430    fn decode(value: Input<'de>, ctx: &mut Context, coerce: bool) -> Option<Self> {
431        if value.is_null() {
432            Some(None)
433        } else {
434            T::decode(value, ctx, coerce).map(Some)
435        }
436    }
437    fn encode(&self, ctx: &mut Context) -> Value {
438        self.as_ref().map_or(Value::Null, |v| v.encode(ctx))
439    }
440    fn encode_input(&self, ctx: &mut Context) -> Value {
441        self.as_ref().map_or(Value::Null, |v| v.encode_input(ctx))
442    }
443    fn schema(ctx: &mut SchemaContext, coerce: bool) -> Value {
444        json!({"anyOf":[T::schema(ctx,coerce),{"type":"null"}]})
445    }
446    fn validate_into(&self, ctx: &mut Context) {
447        if let Some(v) = self {
448            v.validate_into(ctx)
449        }
450    }
451    fn normalize(self, rules: &Rules, ctx: &mut Context) -> Option<Self> {
452        match self {
453            Some(v) => v.normalize(rules, ctx).map(Some),
454            None => Some(None),
455        }
456    }
457    fn validate_rules(&self, rules: &Rules, ctx: &mut Context) {
458        if let Some(v) = self {
459            v.validate_rules(rules, ctx)
460        }
461    }
462    fn missing() -> Option<Self> {
463        Some(None)
464    }
465    fn allows_missing() -> bool {
466        true
467    }
468    fn kind() -> TypeKind {
469        T::kind()
470    }
471    fn async_required(seen: &mut HashSet<&'static str>) -> bool {
472        T::async_required(seen)
473    }
474}
475impl<'de, T: BorrowType<'de>> BorrowType<'de> for Box<T> {
476    fn prepare_default(self, ctx: &mut Context) -> Option<Self> {
477        (*self).prepare_default(ctx).map(Box::new)
478    }
479    fn decode(value: Input<'de>, ctx: &mut Context, coerce: bool) -> Option<Self> {
480        T::decode(value, ctx, coerce).map(Box::new)
481    }
482    fn encode(&self, ctx: &mut Context) -> Value {
483        (**self).encode(ctx)
484    }
485    fn encode_input(&self, ctx: &mut Context) -> Value {
486        (**self).encode_input(ctx)
487    }
488    fn schema(ctx: &mut SchemaContext, coerce: bool) -> Value {
489        T::schema(ctx, coerce)
490    }
491    fn validate_into(&self, ctx: &mut Context) {
492        (**self).validate_into(ctx)
493    }
494    fn normalize(self, rules: &Rules, ctx: &mut Context) -> Option<Self> {
495        (*self).normalize(rules, ctx).map(Box::new)
496    }
497    fn validate_rules(&self, rules: &Rules, ctx: &mut Context) {
498        (**self).validate_rules(rules, ctx)
499    }
500    fn missing() -> Option<Self> {
501        T::missing().map(Box::new)
502    }
503    fn allows_missing() -> bool {
504        T::allows_missing()
505    }
506    fn kind() -> TypeKind {
507        T::kind()
508    }
509    fn async_required(seen: &mut HashSet<&'static str>) -> bool {
510        T::async_required(seen)
511    }
512}
513impl<'de, T: BorrowType<'de>> BorrowType<'de> for Vec<T> {
514    fn validate_rules(&self, rules: &Rules, ctx: &mut Context) {
515        rules.validate_length(self.len(), ctx)
516    }
517    fn prepare_default(self, ctx: &mut Context) -> Option<Self> {
518        let mut result = Vec::with_capacity(self.len());
519        let mut complete = true;
520        for (i, value) in self.into_iter().enumerate() {
521            match ctx.at(i, |ctx| value.prepare_default(ctx)) {
522                Some(v) => result.push(v),
523                None => complete = false,
524            }
525        }
526        complete.then_some(result)
527    }
528    fn decode(value: Input<'de>, ctx: &mut Context, coerce: bool) -> Option<Self> {
529        let items = value.array(ctx)?;
530        let mut result = Vec::with_capacity(items.len());
531        let mut complete = true;
532        for (i, value) in items.into_iter().enumerate() {
533            match ctx.at(i, |ctx| T::decode(value, ctx, coerce)) {
534                Some(v) => result.push(v),
535                None => complete = false,
536            }
537        }
538        complete.then_some(result)
539    }
540    fn encode(&self, ctx: &mut Context) -> Value {
541        Value::Array(
542            self.iter()
543                .enumerate()
544                .map(|(i, v)| ctx.at(i, |ctx| v.encode(ctx)))
545                .collect(),
546        )
547    }
548    fn encode_input(&self, ctx: &mut Context) -> Value {
549        Value::Array(
550            self.iter()
551                .enumerate()
552                .map(|(i, v)| ctx.at(i, |ctx| v.encode_input(ctx)))
553                .collect(),
554        )
555    }
556    fn schema(ctx: &mut SchemaContext, coerce: bool) -> Value {
557        json!({"type":"array","items":T::schema(ctx,coerce)})
558    }
559    fn validate_into(&self, ctx: &mut Context) {
560        for (i, v) in self.iter().enumerate() {
561            ctx.at(i, |ctx| v.validate_into(ctx));
562        }
563    }
564    fn kind() -> TypeKind {
565        TypeKind::Array
566    }
567    fn async_required(seen: &mut HashSet<&'static str>) -> bool {
568        T::async_required(seen)
569    }
570}
571impl<'de, T: BorrowType<'de>, const N: usize> BorrowType<'de> for [T; N] {
572    fn validate_rules(&self, rules: &Rules, ctx: &mut Context) {
573        rules.validate_length(self.len(), ctx)
574    }
575    fn prepare_default(self, ctx: &mut Context) -> Option<Self> {
576        <Vec<T> as BorrowType>::prepare_default(Vec::from(self), ctx)?
577            .try_into()
578            .ok()
579    }
580    fn decode(value: Input<'de>, ctx: &mut Context, coerce: bool) -> Option<Self> {
581        let items = <Vec<T> as BorrowType>::decode(value, ctx, coerce)?;
582        let len = items.len();
583        items
584            .try_into()
585            .map_err(|_| {
586                ctx.push(
587                    ValidationError::new(
588                        "array_length",
589                        format!("array must contain exactly {N} items"),
590                    )
591                    .with_param("actual", len),
592                )
593            })
594            .ok()
595    }
596    fn encode(&self, ctx: &mut Context) -> Value {
597        Value::Array(
598            self.iter()
599                .enumerate()
600                .map(|(i, v)| ctx.at(i, |ctx| v.encode(ctx)))
601                .collect(),
602        )
603    }
604    fn encode_input(&self, ctx: &mut Context) -> Value {
605        Value::Array(
606            self.iter()
607                .enumerate()
608                .map(|(i, v)| ctx.at(i, |ctx| v.encode_input(ctx)))
609                .collect(),
610        )
611    }
612    fn schema(ctx: &mut SchemaContext, coerce: bool) -> Value {
613        json!({"type":"array","items":T::schema(ctx,coerce),"minItems":N,"maxItems":N})
614    }
615    fn validate_into(&self, ctx: &mut Context) {
616        for (i, v) in self.iter().enumerate() {
617            ctx.at(i, |ctx| v.validate_into(ctx));
618        }
619    }
620    fn kind() -> TypeKind {
621        TypeKind::Array
622    }
623    fn async_required(seen: &mut HashSet<&'static str>) -> bool {
624        T::async_required(seen)
625    }
626}
627impl<'de, T: BorrowType<'de>> BorrowType<'de> for BTreeMap<String, T> {
628    fn validate_rules(&self, rules: &Rules, ctx: &mut Context) {
629        rules.validate_length(self.len(), ctx)
630    }
631    fn prepare_default(self, ctx: &mut Context) -> Option<Self> {
632        let mut result = Self::new();
633        let mut complete = true;
634        for (k, v) in self {
635            match ctx.at(k.clone(), |ctx| v.prepare_default(ctx)) {
636                Some(v) => {
637                    result.insert(k, v);
638                }
639                None => complete = false,
640            }
641        }
642        complete.then_some(result)
643    }
644    fn decode(value: Input<'de>, ctx: &mut Context, coerce: bool) -> Option<Self> {
645        let mut result = Self::new();
646        let mut complete = true;
647        for (k, v) in value.object(ctx)? {
648            match ctx.at(k.clone(), |ctx| T::decode(v, ctx, coerce)) {
649                Some(v) => {
650                    result.insert(k, v);
651                }
652                None => complete = false,
653            }
654        }
655        complete.then_some(result)
656    }
657    fn encode(&self, ctx: &mut Context) -> Value {
658        Value::Object(
659            self.iter()
660                .map(|(k, v)| (k.clone(), ctx.at(k.clone(), |ctx| v.encode(ctx))))
661                .collect(),
662        )
663    }
664    fn encode_input(&self, ctx: &mut Context) -> Value {
665        Value::Object(
666            self.iter()
667                .map(|(k, v)| (k.clone(), ctx.at(k.clone(), |ctx| v.encode_input(ctx))))
668                .collect(),
669        )
670    }
671    fn schema(ctx: &mut SchemaContext, coerce: bool) -> Value {
672        json!({"type":"object","additionalProperties":T::schema(ctx,coerce)})
673    }
674    fn validate_into(&self, ctx: &mut Context) {
675        for (k, v) in self {
676            ctx.at(k.clone(), |ctx| v.validate_into(ctx));
677        }
678    }
679    fn kind() -> TypeKind {
680        TypeKind::Object
681    }
682    fn async_required(seen: &mut HashSet<&'static str>) -> bool {
683        T::async_required(seen)
684    }
685}
686impl<'de, T: BorrowType<'de>, S: BuildHasher + Default> BorrowType<'de> for HashMap<String, T, S> {
687    fn validate_rules(&self, rules: &Rules, ctx: &mut Context) {
688        rules.validate_length(self.len(), ctx)
689    }
690    fn prepare_default(self, ctx: &mut Context) -> Option<Self> {
691        <BTreeMap<String, T> as BorrowType>::prepare_default(self.into_iter().collect(), ctx)
692            .map(|v| v.into_iter().collect())
693    }
694    fn decode(value: Input<'de>, ctx: &mut Context, coerce: bool) -> Option<Self> {
695        <BTreeMap<String, T> as BorrowType>::decode(value, ctx, coerce)
696            .map(|v| v.into_iter().collect())
697    }
698    fn encode(&self, ctx: &mut Context) -> Value {
699        Value::Object(
700            self.iter()
701                .map(|(k, v)| (k.clone(), ctx.at(k.clone(), |ctx| v.encode(ctx))))
702                .collect(),
703        )
704    }
705    fn encode_input(&self, ctx: &mut Context) -> Value {
706        Value::Object(
707            self.iter()
708                .map(|(k, v)| (k.clone(), ctx.at(k.clone(), |ctx| v.encode_input(ctx))))
709                .collect(),
710        )
711    }
712    fn schema(ctx: &mut SchemaContext, coerce: bool) -> Value {
713        <BTreeMap<String, T> as BorrowType>::schema(ctx, coerce)
714    }
715    fn validate_into(&self, ctx: &mut Context) {
716        for (k, v) in self {
717            ctx.at(k.clone(), |ctx| v.validate_into(ctx));
718        }
719    }
720    fn kind() -> TypeKind {
721        TypeKind::Object
722    }
723    fn async_required(seen: &mut HashSet<&'static str>) -> bool {
724        T::async_required(seen)
725    }
726}
727
728owned!(Box<RawValue>);