json_model/attribute/
pointer_path.rs1use super::{AllowedType, Attribute};
2use crate::definition::Type;
3use crate::error::{Error, ValidationError};
4use crate::validator::{Context, DocumentPath, State};
5
6use std::collections::HashSet;
7
8#[derive(Debug)]
9pub struct PointerPath {
10 name: String,
11 ptr: String,
12}
13
14impl PointerPath {
15 pub fn new(state: &mut State, mut path: DocumentPath, ctx: &Context) -> Result<Self, Error> {
16 let obj = ctx.raw_definition();
17
18 match Type::new(obj, path.clone())? {
19 Type::Pointer => (),
20 typ => return Err(Error::ForbiddenType { path, typ }),
21 };
22
23 let ptr = match obj.get(ctx.name().as_str()) {
24 Some(ptr_path) => match ptr_path.as_str() {
25 Some(path) => path,
26 None => {
27 path.add(ctx.name().as_str());
28 return Err(Error::InvalidValue {
29 path,
30 value: ptr_path.clone(),
31 });
32 }
33 },
34 None => {
35 return Err(Error::MissingAttribute {
36 path,
37 attr: ctx.name(),
38 })
39 }
40 };
41
42 state.add_unresolved_pointer(ptr.to_string(), ctx.ptr());
43
44 Ok(PointerPath {
45 name: ctx.name(),
46 ptr: ptr.to_string(),
47 })
48 }
49
50 pub fn allowed_types() -> HashSet<AllowedType> {
51 let mut set = HashSet::<AllowedType>::new();
52 set.insert(AllowedType::new(Type::Pointer, true));
53 set
54 }
55
56 pub fn build(
57 state: &mut State,
58 path: DocumentPath,
59 ctx: &Context,
60 ) -> Result<Box<Attribute>, Error> {
61 Ok(Box::new(PointerPath::new(state, path, ctx)?))
62 }
63}
64
65impl Attribute for PointerPath {
66 fn validate(
67 &self,
68 state: &State,
69 path: Vec<String>,
70 input: &serde_json::Value,
71 ) -> Result<(), ValidationError> {
72 let def = match state.get_definition(self.ptr.as_str()) {
73 Some(def) => def,
74 None => return Err(ValidationError::UndefinedDefinition),
75 };
76
77 def.validate(state, input, path)?;
78
79 Ok(())
80 }
81}