json_ld_syntax_next/
try_from_json.rs

1use crate::{
2	context::InvalidContext, Container, ContainerKind, Direction, LenientLangTagBuf, Nullable,
3};
4use iref::IriRefBuf;
5
6pub trait TryFromJson: Sized {
7	type Error;
8
9	fn try_from_json(value: json_syntax::Value) -> Result<Self, Self::Error>;
10}
11
12impl crate::TryFromJson for bool {
13	type Error = crate::Unexpected;
14
15	fn try_from_json(value: json_syntax::Value) -> Result<Self, Self::Error> {
16		match value {
17			json_syntax::Value::Boolean(b) => Ok(b),
18			unexpected => Err(crate::Unexpected(
19				unexpected.kind(),
20				&[json_syntax::Kind::Boolean],
21			)),
22		}
23	}
24}
25
26impl TryFromJson for IriRefBuf {
27	type Error = InvalidContext;
28
29	fn try_from_json(value: json_syntax::Value) -> Result<Self, InvalidContext> {
30		match value {
31			json_syntax::Value::String(s) => match IriRefBuf::new(s.into_string()) {
32				Ok(iri_ref) => Ok(iri_ref),
33				Err(e) => Err(InvalidContext::InvalidIriRef(e.0)),
34			},
35			unexpected => Err(InvalidContext::Unexpected(
36				unexpected.kind(),
37				&[json_syntax::Kind::String],
38			)),
39		}
40	}
41}
42
43impl TryFromJson for LenientLangTagBuf {
44	type Error = InvalidContext;
45
46	fn try_from_json(value: json_syntax::Value) -> Result<Self, InvalidContext> {
47		match value {
48			json_syntax::Value::String(s) => {
49				let (lang, _) = LenientLangTagBuf::new(s.into_string());
50				Ok(lang)
51			}
52			unexpected => Err(InvalidContext::Unexpected(
53				unexpected.kind(),
54				&[json_syntax::Kind::String],
55			)),
56		}
57	}
58}
59
60impl TryFromJson for Direction {
61	type Error = InvalidContext;
62
63	fn try_from_json(value: json_syntax::Value) -> Result<Self, InvalidContext> {
64		match value {
65			json_syntax::Value::String(s) => match Direction::try_from(s.as_str()) {
66				Ok(d) => Ok(d),
67				Err(_) => Err(InvalidContext::InvalidDirection),
68			},
69			unexpected => Err(InvalidContext::Unexpected(
70				unexpected.kind(),
71				&[json_syntax::Kind::String],
72			)),
73		}
74	}
75}
76
77impl<T: TryFromJson> TryFromJson for Nullable<T> {
78	type Error = T::Error;
79
80	fn try_from_json(value: json_syntax::Value) -> Result<Self, Self::Error> {
81		match value {
82			json_syntax::Value::Null => Ok(Self::Null),
83			some => T::try_from_json(some).map(Self::Some),
84		}
85	}
86}
87
88impl TryFromJson for Container {
89	type Error = InvalidContext;
90
91	fn try_from_json(value: json_syntax::Value) -> Result<Self, InvalidContext> {
92		match value {
93			json_syntax::Value::Array(a) => {
94				let mut container = Vec::new();
95
96				for item in a {
97					container.push(ContainerKind::try_from_json(item)?)
98				}
99
100				Ok(Self::Many(container))
101			}
102			other => ContainerKind::try_from_json(other).map(Into::into),
103		}
104	}
105}
106
107impl TryFromJson for ContainerKind {
108	type Error = InvalidContext;
109
110	fn try_from_json(value: json_syntax::Value) -> Result<Self, InvalidContext> {
111		match value {
112			json_syntax::Value::String(s) => match ContainerKind::try_from(s.as_str()) {
113				Ok(t) => Ok(t),
114				Err(_) => Err(InvalidContext::InvalidTermDefinition),
115			},
116			unexpected => Err(InvalidContext::Unexpected(
117				unexpected.kind(),
118				&[json_syntax::Kind::String],
119			)),
120		}
121	}
122}