cedar_policy_cli/command/
translate_schema.rs1use cedar_policy::SchemaFragment;
18use clap::Args;
19use miette::{IntoDiagnostic, Result};
20
21use crate::{read_from_file_or_stdin, CedarExitCode};
22
23#[derive(Debug, Clone, Copy, clap::ValueEnum)]
25pub enum SchemaTranslationDirection {
26 JsonToCedar,
28 CedarToJson,
30 CedarToJsonWithResolvedTypes,
35}
36
37#[derive(Args, Debug)]
38pub struct TranslateSchemaArgs {
39 #[arg(long)]
41 pub direction: SchemaTranslationDirection,
42 #[arg(short = 's', long = "schema", value_name = "FILE")]
45 pub input_file: Option<String>,
46}
47
48pub fn translate_schema(args: &TranslateSchemaArgs) -> CedarExitCode {
49 match translate_schema_inner(args) {
50 Ok(sf) => {
51 println!("{sf}");
52 CedarExitCode::Success
53 }
54 Err(err) => {
55 eprintln!("{err:?}");
56 CedarExitCode::Failure
57 }
58 }
59}
60
61fn translate_schema_inner(args: &TranslateSchemaArgs) -> Result<String> {
62 let translate = match args.direction {
63 SchemaTranslationDirection::JsonToCedar => translate_schema_to_cedar,
64 SchemaTranslationDirection::CedarToJson => translate_schema_to_json,
65 SchemaTranslationDirection::CedarToJsonWithResolvedTypes => {
66 translate_schema_to_json_with_resolved_types
67 }
68 };
69 read_from_file_or_stdin(args.input_file.as_ref(), "schema").and_then(translate)
70}
71
72fn translate_schema_to_cedar(json_src: impl AsRef<str>) -> Result<String> {
73 let fragment = SchemaFragment::from_json_str(json_src.as_ref())?;
74 let output = fragment.to_cedarschema()?;
75 Ok(output)
76}
77
78fn translate_schema_to_json(cedar_src: impl AsRef<str>) -> Result<String> {
79 let (fragment, warnings) = SchemaFragment::from_cedarschema_str(cedar_src.as_ref())?;
80 for warning in warnings {
81 let report = miette::Report::new(warning);
82 eprintln!("{report:?}");
83 }
84 let output = fragment.to_json_string()?;
85 Ok(output)
86}
87
88fn translate_schema_to_json_with_resolved_types(cedar_src: impl AsRef<str>) -> Result<String> {
89 match cedar_policy::schema_str_to_json_with_resolved_types(cedar_src.as_ref()) {
90 Ok((json_value, warnings)) => {
91 for warning in &warnings {
93 eprintln!("{warning}");
94 }
95
96 serde_json::to_string_pretty(&json_value).into_diagnostic()
98 }
99 Err(error) => {
100 Err(miette::Report::new(error))
102 }
103 }
104}