cedar_policy_validator/human_schema/
parser.rs1use std::sync::Arc;
18
19use lalrpop_util::lalrpop_mod;
20use miette::Diagnostic;
21use thiserror::Error;
22
23use super::{
24 ast::Schema,
25 err::{self, ParseError, ParseErrors, SchemaWarning, ToJsonSchemaErrors},
26 to_json_schema::{custom_schema_to_json_schema, custom_type_to_json_type},
27};
28
29lalrpop_mod!(
30 #[allow(warnings, unused)]
31 #[allow(clippy::unwrap_used)]
33 #[allow(clippy::indexing_slicing)]
35 #[allow(clippy::unreachable)]
37 #[allow(clippy::panic)]
39 pub grammar,
40 "/src/human_schema/grammar.rs"
41);
42
43fn parse_collect_errors<'a, P, T>(
47 parser: &P,
48 parse: impl FnOnce(
49 &P,
50 &mut Vec<err::RawErrorRecovery<'a>>,
51 &Arc<str>,
52 &'a str,
53 ) -> Result<T, err::RawParseError<'a>>,
54 text: &'a str,
55) -> Result<T, err::ParseErrors> {
56 let mut errs = Vec::new();
57 let result = parse(parser, &mut errs, &Arc::from(text), text);
58
59 let errors = errs
60 .into_iter()
61 .map(Into::into)
62 .collect::<Vec<ParseError>>();
63 let parsed = match result {
64 Ok(parsed) => parsed,
65 Err(e) => {
66 return Err(ParseErrors::new(e.into(), errors));
67 }
68 };
69 match ParseErrors::from_iter(errors) {
70 Some(errors) => Err(errors),
71 None => Ok(parsed),
73 }
74}
75
76lazy_static::lazy_static! {
78 static ref SCHEMA_PARSER: grammar::SchemaParser = grammar::SchemaParser::new();
79 static ref TYPE_PARSER: grammar::TypeParser = grammar::TypeParser::new();
80}
81
82#[derive(Debug, Diagnostic, Error)]
83pub enum HumanSyntaxParseErrors {
84 #[error(transparent)]
85 #[diagnostic(transparent)]
86 NaturalSyntaxError(#[from] err::ParseErrors),
87 #[error(transparent)]
88 #[diagnostic(transparent)]
89 JsonError(#[from] ToJsonSchemaErrors),
90}
91
92pub fn parse_type(src: &str) -> Result<crate::SchemaType, HumanSyntaxParseErrors> {
93 let ty = parse_collect_errors(&*TYPE_PARSER, grammar::TypeParser::parse, src)?;
94 Ok(custom_type_to_json_type(ty)?)
95}
96
97pub fn parse_natural_schema_fragment(
98 src: &str,
99) -> Result<(crate::SchemaFragment, impl Iterator<Item = SchemaWarning>), HumanSyntaxParseErrors> {
100 let ast: Schema = parse_collect_errors(&*SCHEMA_PARSER, grammar::SchemaParser::parse, src)?;
101 let tuple = custom_schema_to_json_schema(ast)?;
102 Ok(tuple)
103}
104
105pub fn parse_schema(text: &str) -> Result<Schema, err::ParseErrors> {
107 parse_collect_errors(&*SCHEMA_PARSER, grammar::SchemaParser::parse, text)
108}