diff --git a/Justfile b/Justfile index 3f5dac0..583e92d 100644 --- a/Justfile +++ b/Justfile @@ -7,6 +7,7 @@ fmt: just --unstable --fmt shfmt -w . nix fmt . + cargo fmt lint: cargo clippy --fix --allow-dirty --allow-staged diff --git a/cargo-sync-readme2/src/config.rs b/cargo-sync-readme2/src/config.rs index d651b7e..3a75683 100644 --- a/cargo-sync-readme2/src/config.rs +++ b/cargo-sync-readme2/src/config.rs @@ -114,4 +114,3 @@ pub struct Package { pub metadata: Metadata, pub rustdoc_json: Utf8PathBuf, } - diff --git a/cargo-sync-readme2/src/content/badge.rs b/cargo-sync-readme2/src/content/badge.rs index 4a1cd71..1bdf7d0 100644 --- a/cargo-sync-readme2/src/content/badge.rs +++ b/cargo-sync-readme2/src/content/badge.rs @@ -41,7 +41,9 @@ pub fn create(package: &Package) -> String { badges.push(format!("![Crates.io Downloads](https://img.shields.io/crates/dv/{name}/{version}.svg?&label=downloads&style={badge_style})")); } - let repository = repository.as_ref().and_then(|r| r.strip_prefix("https://github.com/")); + let repository = repository + .as_ref() + .and_then(|r| r.strip_prefix("https://github.com/")); match (&metadata.badges.codecov, repository) { (Codecov::Simple(false), _) => {} @@ -56,7 +58,12 @@ pub fn create(package: &Package) -> String { } } - for CustomBadge { link, name: text, url } in &metadata.custom_badges { + for CustomBadge { + link, + name: text, + url, + } in &metadata.custom_badges + { let badge = format!("![{text}]({url})"); if let Some(link) = link { badges.push(format!("[{badge}]({link})")) @@ -67,4 +74,3 @@ pub fn create(package: &Package) -> String { badges.join("\n") } - diff --git a/cargo-sync-readme2/src/content/mod.rs b/cargo-sync-readme2/src/content/mod.rs index 411714b..5bf5391 100644 --- a/cargo-sync-readme2/src/content/mod.rs +++ b/cargo-sync-readme2/src/content/mod.rs @@ -17,4 +17,3 @@ pub fn create(package: &Package) -> anyhow::Result { badge: badge::create(package), }) } - diff --git a/cargo-sync-readme2/src/content/rustdoc/code_block.rs b/cargo-sync-readme2/src/content/rustdoc/code_block.rs index 1104095..4dbbfe6 100644 --- a/cargo-sync-readme2/src/content/rustdoc/code_block.rs +++ b/cargo-sync-readme2/src/content/rustdoc/code_block.rs @@ -2,7 +2,9 @@ use std::borrow::Cow; use pulldown_cmark::{CodeBlockKind, CowStr, Event, Tag, TagEnd}; -pub(super) fn convert<'a, 'b>(events: impl IntoIterator> + 'b) -> impl Iterator> + 'b { +pub(super) fn convert<'a, 'b>( + events: impl IntoIterator> + 'b, +) -> impl Iterator> + 'b { let mut in_codeblock = None; events.into_iter().map(move |mut event| { if let Some(is_rust) = in_codeblock { @@ -61,19 +63,29 @@ pub(super) fn convert<'a, 'b>(events: impl IntoIterator> + 'b) } fn is_attribute_tag(tag: &str) -> bool { - matches!(tag, "" | "ignore" | "should_panic" | "no_run" | "compile_fail" | "standalone_crate" | "test_harness") - || tag - .strip_prefix("edition") - .map(|x| x.len() == 4 && x.chars().all(|ch| ch.is_ascii_digit())) - .unwrap_or_default() + matches!( + tag, + "" | "ignore" + | "should_panic" + | "no_run" + | "compile_fail" + | "standalone_crate" + | "test_harness" + ) || tag + .strip_prefix("edition") + .map(|x| x.len() == 4 && x.chars().all(|ch| ch.is_ascii_digit())) + .unwrap_or_default() } fn update_codeblock_tag(tag: &mut CowStr<'_>) -> bool { let mut tag_count = 0; - let is_rust = tag.split(',').filter(|tag| !is_attribute_tag(tag)).all(|tag| { - tag_count += 1; - tag == "rust" - }); + let is_rust = tag + .split(',') + .filter(|tag| !is_attribute_tag(tag)) + .all(|tag| { + tag_count += 1; + tag == "rust" + }); if is_rust && tag_count == 0 { if tag.is_empty() { *tag = "rust".into(); @@ -83,4 +95,3 @@ fn update_codeblock_tag(tag: &mut CowStr<'_>) -> bool { } is_rust } - diff --git a/cargo-sync-readme2/src/content/rustdoc/heading.rs b/cargo-sync-readme2/src/content/rustdoc/heading.rs index 242578b..4d6ee68 100644 --- a/cargo-sync-readme2/src/content/rustdoc/heading.rs +++ b/cargo-sync-readme2/src/content/rustdoc/heading.rs @@ -1,6 +1,8 @@ use pulldown_cmark::{Event, Tag, TagEnd}; -pub(super) fn convert<'a, 'b>(events: impl IntoIterator> + 'b) -> impl Iterator> + 'b { +pub(super) fn convert<'a, 'b>( + events: impl IntoIterator> + 'b, +) -> impl Iterator> + 'b { use pulldown_cmark::HeadingLevel::*; events.into_iter().map(|mut event| { match &mut event { @@ -19,4 +21,3 @@ pub(super) fn convert<'a, 'b>(events: impl IntoIterator> + 'b) event }) } - diff --git a/cargo-sync-readme2/src/content/rustdoc/intra_link.rs b/cargo-sync-readme2/src/content/rustdoc/intra_link.rs index 914d39d..ddcd68a 100644 --- a/cargo-sync-readme2/src/content/rustdoc/intra_link.rs +++ b/cargo-sync-readme2/src/content/rustdoc/intra_link.rs @@ -6,7 +6,9 @@ use std::hash::BuildHasher; use std::rc::Rc; use pulldown_cmark::{BrokenLink, CowStr, Event, Options, Tag}; -use rustdoc_types::{Crate, Id, Item, ItemEnum, ItemKind, ItemSummary, MacroKind, StructKind, VariantKind}; +use rustdoc_types::{ + Crate, Id, Item, ItemEnum, ItemKind, ItemSummary, MacroKind, StructKind, VariantKind, +}; trait CowStrExt<'a> { fn as_str(&'a self) -> &'a str; @@ -36,7 +38,10 @@ impl Parser<(), ()> { item: &'a Item, local_html_root_url: &str, mappings: &BTreeMap, - ) -> Parser) -> Option>, impl FnMut(Event<'a>) -> Option>> { + ) -> Parser< + impl FnMut(BrokenLink<'_>) -> Option>, + impl FnMut(Event<'a>) -> Option>, + > { let url_map = Rc::new(resolve_links(doc, item, local_html_root_url, mappings)); let broken_link_callback = { @@ -64,8 +69,12 @@ where where 'a: 'b, { - pulldown_cmark::Parser::new_with_broken_link_callback(doc, Options::all(), Some(&mut self.broken_link_callback)) - .filter_map(&mut self.iterator_map) + pulldown_cmark::Parser::new_with_broken_link_callback( + doc, + Options::all(), + Some(&mut self.broken_link_callback), + ) + .filter_map(&mut self.iterator_map) } } @@ -147,7 +156,11 @@ fn extra_paths<'doc, S: BuildHasher + Default>( let mut heap: BinaryHeap> = index .iter() .map(|(id, item)| { - let depth = if paths.contains_key(id) { 0 } else { usize::MAX }; + let depth = if paths.contains_key(id) { + 0 + } else { + usize::MAX + }; HeapItem { depth: Reverse(depth), id, @@ -262,7 +275,10 @@ fn item_children<'doc>(parent: &'doc Item) -> Option(url_map: &BTreeMap<&str, Option>, mut event: Event<'a>) -> Option> { +fn convert_link<'a>( + url_map: &BTreeMap<&str, Option>, + mut event: Event<'a>, +) -> Option> { if let Event::Start(Tag::Link { dest_url: url, .. }) = &mut event && let Some(full_url) = url_map.get(url.as_ref()) { @@ -298,14 +314,16 @@ fn id_to_url( match (&item.kind, item.path.as_slice()) { (ItemKind::Module, ps) => join(ps, format_args!("index.html")), (ItemKind::Struct, [ps @ .., name]) => join(ps, format_args!("struct.{name}.html")), - (ItemKind::StructField, [ps @ .., struct_name, field]) => { - join(ps, format_args!("struct.{struct_name}.html#structfield.{field}")) - } + (ItemKind::StructField, [ps @ .., struct_name, field]) => join( + ps, + format_args!("struct.{struct_name}.html#structfield.{field}"), + ), (ItemKind::Union, [ps @ .., name]) => join(ps, format_args!("union.{name}.html")), (ItemKind::Enum, [ps @ .., name]) => join(ps, format_args!("enum.{name}.html")), - (ItemKind::Variant, [ps @ .., enum_name, variant_name]) => { - join(ps, format_args!("enum.{enum_name}.html#variant.{variant_name}")) - } + (ItemKind::Variant, [ps @ .., enum_name, variant_name]) => join( + ps, + format_args!("enum.{enum_name}.html#variant.{variant_name}"), + ), (ItemKind::Function, [ps @ .., name]) => join(ps, format_args!("fn.{name}.html")), (ItemKind::TypeAlias, [ps @ .., name]) => join(ps, format_args!("type.{name}.html")), (ItemKind::Constant, [ps @ .., name]) => join(ps, format_args!("constant.{name}.html")), @@ -314,12 +332,14 @@ fn id_to_url( (ItemKind::Macro, [ps @ .., name]) => join(ps, format_args!("macro.{name}.html")), (ItemKind::ProcAttribute, [ps @ .., name]) => join(ps, format_args!("attr.{name}.html")), (ItemKind::ProcDerive, [ps @ .., name]) => join(ps, format_args!("derive.{name}.html")), - (ItemKind::AssocConst, [ps @ .., trait_name, const_name]) => { - join(ps, format_args!("trait.{trait_name}.html#associatedconstant.{const_name}")) - } - (ItemKind::AssocType, [ps @ .., trait_name, type_name]) => { - join(ps, format_args!("trait.{trait_name}.html#associatedtype.{type_name}")) - } + (ItemKind::AssocConst, [ps @ .., trait_name, const_name]) => join( + ps, + format_args!("trait.{trait_name}.html#associatedconstant.{const_name}"), + ), + (ItemKind::AssocType, [ps @ .., trait_name, type_name]) => join( + ps, + format_args!("trait.{trait_name}.html#associatedtype.{type_name}"), + ), (ItemKind::Primitive, [ps @ .., name]) => join(ps, format_args!("primitive.{name}.html")), (item, path) => { eprintln!("unexpected intra-doc link item & path found; path={path:?}, item={item:?}"); @@ -359,4 +379,3 @@ fn item_summary<'doc, S: BuildHasher + Default>( } None } - diff --git a/cargo-sync-readme2/src/content/rustdoc/mod.rs b/cargo-sync-readme2/src/content/rustdoc/mod.rs index 883ff16..966157f 100644 --- a/cargo-sync-readme2/src/content/rustdoc/mod.rs +++ b/cargo-sync-readme2/src/content/rustdoc/mod.rs @@ -11,16 +11,25 @@ pub(super) fn create(package: &Package) -> anyhow::Result { let doc_string = std::fs::read_to_string(&package.rustdoc_json).context("read rustdoc")?; let doc: Crate = serde_json::from_str(&doc_string).context("parse rustdoc")?; let root = doc.index.get(&doc.root).unwrap(); - let local_html_root_url = package.metadata.rustdoc_html_root_url.clone().unwrap_or_else(|| { - format!( - "https://docs.rs/{}/{}", - package.name, - doc.crate_version.as_ref().unwrap_or(&package.version) - ) - }); + let local_html_root_url = package + .metadata + .rustdoc_html_root_url + .clone() + .unwrap_or_else(|| { + format!( + "https://docs.rs/{}/{}", + package.name, + doc.crate_version.as_ref().unwrap_or(&package.version) + ) + }); let root_doc = extract_doc(root); - let mut parser = intra_link::Parser::new(&doc, root, &local_html_root_url, &package.metadata.rustdoc_mappings); + let mut parser = intra_link::Parser::new( + &doc, + root, + &local_html_root_url, + &package.metadata.rustdoc_mappings, + ); let events = parser.events(&root_doc); let events = heading::convert(events); let events = code_block::convert(events); @@ -38,4 +47,3 @@ pub(super) fn create(package: &Package) -> anyhow::Result { fn extract_doc(item: &Item) -> String { item.docs.clone().unwrap_or_default() } - diff --git a/cargo-sync-readme2/src/content/title.rs b/cargo-sync-readme2/src/content/title.rs index b70e02e..f559109 100644 --- a/cargo-sync-readme2/src/content/title.rs +++ b/cargo-sync-readme2/src/content/title.rs @@ -3,4 +3,3 @@ use crate::config::Package; pub(super) fn create(package: &Package) -> String { format!("# {}", package.name) } - diff --git a/cargo-sync-readme2/src/main.rs b/cargo-sync-readme2/src/main.rs index 36e3a62..404c0f9 100644 --- a/cargo-sync-readme2/src/main.rs +++ b/cargo-sync-readme2/src/main.rs @@ -134,8 +134,8 @@ fn main() { } fn load_package(cargo_toml: &Utf8PathBuf, rustdoc_json: Utf8PathBuf) -> anyhow::Result { - let cargo_toml = - cargo_toml::Manifest::::from_path_with_metadata(cargo_toml).context("cargo toml")?; + let cargo_toml = cargo_toml::Manifest::::from_path_with_metadata(cargo_toml) + .context("cargo toml")?; let pkg = cargo_toml.package(); Ok(Package { @@ -157,7 +157,8 @@ fn render_readme(package: &Package, readme_path: &Utf8Path) -> anyhow::Result<(S fn sync(args: SyncArgs) -> anyhow::Result<()> { let package = load_package(&args.cargo_toml, args.rustdoc_json)?; - let (_, rendered) = render_readme(&package, &args.readme_md).with_context(|| args.readme_md.to_string())?; + let (_, rendered) = + render_readme(&package, &args.readme_md).with_context(|| args.readme_md.to_string())?; std::fs::write(&args.readme_md, rendered).context("write readme")?; println!("synced {}", args.readme_md); Ok(()) @@ -169,7 +170,8 @@ fn test(args: TestArgs) -> anyhow::Result<()> { } fn test_package(package: &Package, readme_path: &Utf8Path) -> anyhow::Result<()> { - let (source, rendered) = render_readme(package, readme_path).with_context(|| readme_path.to_string())?; + let (source, rendered) = + render_readme(package, readme_path).with_context(|| readme_path.to_string())?; if rendered == source { println!("readme matches render: {}", readme_path); @@ -224,20 +226,33 @@ fn build_rustdoc_json(packages: &[WorkspacePackage], target_dir: &Utf8Path) -> a return Ok(()); } - println!("building rustdoc json for {}", packages.iter().map(|p| p.name.clone()).collect::>().join(", ")); + println!( + "building rustdoc json for {}", + packages + .iter() + .map(|p| p.name.clone()) + .collect::>() + .join(", ") + ); let mut cmd = ProcessCommand::new("cargo"); cmd.env("RUSTC_BOOTSTRAP", "1") .env("RUSTDOCFLAGS", "-Z unstable-options --output-format json") .arg("doc") .arg("--no-deps") - .arg("--target-dir").arg(target_dir); + .arg("--target-dir") + .arg(target_dir); let mut features = Vec::new(); for pkg in packages { cmd.args(["-p", &pkg.name]); - features.extend(pkg.metadata.features.iter().map(|f| format!("{}/{f}", pkg.name))); + features.extend( + pkg.metadata + .features + .iter() + .map(|f| format!("{}/{f}", pkg.name)), + ); } if !features.is_empty() { @@ -267,7 +282,10 @@ fn workspace(args: WorkspaceArgs) -> anyhow::Result<()> { for pkg in &packages { let json_name = pkg.name.replace('-', "_"); - let rustdoc_json = args.target_dir.join("doc").join(format!("{}.json", json_name)); + let rustdoc_json = args + .target_dir + .join("doc") + .join(format!("{}.json", json_name)); let package = load_package(&pkg.manifest_path, rustdoc_json)?; let readme_path = pkg.manifest_path.parent().unwrap().join(&pkg.readme_path); @@ -292,7 +310,8 @@ fn workspace(args: WorkspaceArgs) -> anyhow::Result<()> { fn sync_package(package: &Package, readme_path: &Utf8Path) -> anyhow::Result<()> { let readme_path_buf = readme_path.to_path_buf(); - let (_, rendered) = render_readme(package, &readme_path_buf).with_context(|| readme_path.to_string())?; + let (_, rendered) = + render_readme(package, &readme_path_buf).with_context(|| readme_path.to_string())?; let original = std::fs::read_to_string(readme_path).context("read original readme")?; if original == rendered { println!("readme is already in sync: {}", readme_path); @@ -352,4 +371,3 @@ fn diff(old: &str, new: &str) -> String { output } - diff --git a/cargo-sync-readme2/src/render.rs b/cargo-sync-readme2/src/render.rs index a2ef5ea..4f429e9 100644 --- a/cargo-sync-readme2/src/render.rs +++ b/cargo-sync-readme2/src/render.rs @@ -4,11 +4,13 @@ use anyhow::Context; use crate::content::Content; -static MARKER_REGEX: std::sync::LazyLock = - std::sync::LazyLock::new(|| regex::Regex::new(r#""#).expect("bad regex")); +static MARKER_REGEX: std::sync::LazyLock = std::sync::LazyLock::new(|| { + regex::Regex::new(r#""#).expect("bad regex") +}); -static CLOSE_MARKER_REGEX: std::sync::LazyLock = - std::sync::LazyLock::new(|| regex::Regex::new(r#""#).expect("bad regex")); +static CLOSE_MARKER_REGEX: std::sync::LazyLock = std::sync::LazyLock::new(|| { + regex::Regex::new(r#""#).expect("bad regex") +}); #[derive(Debug)] enum MarkerCategory { @@ -75,7 +77,11 @@ pub fn render(readme: &str, content: &Content) -> anyhow::Result { skip_until = end; } - markers.push(Marker { category, start, end }); + markers.push(Marker { + category, + start, + end, + }); } let mut readme_builder = String::new(); @@ -95,7 +101,12 @@ pub fn render(readme: &str, content: &Content) -> anyhow::Result { .trim(); if content.is_empty() { - writeln!(&mut readme_builder, "", marker.category).expect("write failed"); + writeln!( + &mut readme_builder, + "", + marker.category + ) + .expect("write failed"); } else { writeln!( &mut readme_builder, @@ -110,4 +121,3 @@ pub fn render(readme: &str, content: &Content) -> anyhow::Result { Ok(readme_builder) } - diff --git a/embed-changelog/src/macro_impl.rs b/embed-changelog/src/macro_impl.rs index 3738e5b..297e144 100644 --- a/embed-changelog/src/macro_impl.rs +++ b/embed-changelog/src/macro_impl.rs @@ -11,8 +11,9 @@ struct ChangeLogEntry<'a> { lines: Vec<&'a str>, } -static HEADING_REGEX: std::sync::LazyLock = - std::sync::LazyLock::new(|| regex::Regex::new(r"^## \[([^]]+)\](?:\(([^)]+)\))?(?: - (\d{4}-\d{2}-\d{2}))?$").unwrap()); +static HEADING_REGEX: std::sync::LazyLock = std::sync::LazyLock::new(|| { + regex::Regex::new(r"^## \[([^]]+)\](?:\(([^)]+)\))?(?: - (\d{4}-\d{2}-\d{2}))?$").unwrap() +}); fn parse_changelog(changelog: &str) -> Result>, String> { let mut entries = Vec::new(); @@ -98,9 +99,10 @@ pub(crate) fn changelog(_: TokenStream, item: TokenStream) -> syn::Result -#[derive(serde_derive::Serialize, serde_derive::Deserialize, Default, Clone, PartialEq, bon::Builder)] +#[derive( + serde_derive::Serialize, serde_derive::Deserialize, Default, Clone, PartialEq, bon::Builder, +)] #[cfg_attr(feature = "debug", derive(Debug))] #[builder(on(_, into))] #[non_exhaustive] diff --git a/openapiv3_1/src/encoding.rs b/openapiv3_1/src/encoding.rs index 83285e4..372de60 100644 --- a/openapiv3_1/src/encoding.rs +++ b/openapiv3_1/src/encoding.rs @@ -8,7 +8,9 @@ use super::path::ParameterStyle; /// A single encoding definition applied to a single schema [`Object /// property`](crate::schema::Object::properties). -#[derive(serde_derive::Serialize, serde_derive::Deserialize, Default, Clone, PartialEq, bon::Builder)] +#[derive( + serde_derive::Serialize, serde_derive::Deserialize, Default, Clone, PartialEq, bon::Builder, +)] #[cfg_attr(feature = "debug", derive(Debug))] #[serde(rename_all = "camelCase")] #[non_exhaustive] diff --git a/openapiv3_1/src/extensions.rs b/openapiv3_1/src/extensions.rs index 11febbd..f4b70e4 100644 --- a/openapiv3_1/src/extensions.rs +++ b/openapiv3_1/src/extensions.rs @@ -21,8 +21,12 @@ pub struct Extensions { impl Extensions { /// Create a new extension from an iterator - pub fn new, V: Into>(items: impl IntoIterator) -> Self { - items.into_iter().fold(Self::default(), |this, (k, v)| this.add(k, v)) + pub fn new, V: Into>( + items: impl IntoIterator, + ) -> Self { + items + .into_iter() + .fold(Self::default(), |this, (k, v)| this.add(k, v)) } /// Merge other [`Extensions`] into _`self`_. diff --git a/openapiv3_1/src/lib.rs b/openapiv3_1/src/lib.rs index 5dbe1a6..b781281 100644 --- a/openapiv3_1/src/lib.rs +++ b/openapiv3_1/src/lib.rs @@ -3,7 +3,10 @@ //! A lof the code was taken from [`utoipa`](https://crates.io/crates/utoipa). //! //! The main difference is the full JSON Schema 2020-12 Definitions. -#![cfg_attr(feature = "docs", doc = "\n\nSee the [changelog][changelog] for a full release history.")] +#![cfg_attr( + feature = "docs", + doc = "\n\nSee the [changelog][changelog] for a full release history." +)] #![cfg_attr(feature = "docs", doc = "## Feature flags")] #![cfg_attr(feature = "docs", doc = document_features::document_features!())] //! ## Alternatives @@ -69,7 +72,9 @@ pub mod xml; /// /// See more details at . #[non_exhaustive] -#[derive(serde_derive::Serialize, serde_derive::Deserialize, Default, Clone, PartialEq, bon::Builder)] +#[derive( + serde_derive::Serialize, serde_derive::Deserialize, Default, Clone, PartialEq, bon::Builder, +)] #[cfg_attr(feature = "debug", derive(Debug))] #[serde(rename_all = "camelCase")] #[builder(on(_, into))] @@ -227,7 +232,9 @@ impl OpenApi { other_components .security_schemes .retain(|name, _| !components.security_schemes.contains_key(name)); - components.security_schemes.append(&mut other_components.security_schemes); + components + .security_schemes + .append(&mut other_components.security_schemes); } if let Some(other_security) = &mut other.security { @@ -294,7 +301,11 @@ impl OpenApi { /// Only use this method if you need custom path composition for a specific use case. /// /// `composer` is a function that takes two strings, the base path and the path to nest, and returns the composed path for the API Specification. - pub fn nest_with_path_composer, O: Into, F: Fn(&str, &str) -> String>( + pub fn nest_with_path_composer< + P: Into, + O: Into, + F: Fn(&str, &str) -> String, + >( mut self, path: P, other: O, @@ -353,13 +364,19 @@ impl<'de> serde::Deserialize<'de> for OpenApiVersion { where E: Error, { - let version = v.split('.').flat_map(|digit| digit.parse::()).collect::>(); + let version = v + .split('.') + .flat_map(|digit| digit.parse::()) + .collect::>(); if version.len() == 3 && version.first() == Some(&3) && version.get(1) == Some(&1) { Ok(OpenApiVersion::Version31) } else { let expected: &dyn Expected = &"3.1.0"; - Err(Error::invalid_value(serde::de::Unexpected::Str(&v), expected)) + Err(Error::invalid_value( + serde::de::Unexpected::Str(&v), + expected, + )) } } } @@ -522,14 +539,16 @@ mod tests { "/api/v1/user", PathItem::new( HttpMethod::Get, - Operation::builder().response("200", Response::new("This will not get added")), + Operation::builder() + .response("200", Response::new("This will not get added")), ), ) .path( "/ap/v2/user", PathItem::new( HttpMethod::Get, - Operation::builder().response("200", Response::new("Get user success 2")), + Operation::builder() + .response("200", Response::new("Get user success 2")), ), ) .path( @@ -582,28 +601,32 @@ mod tests { "/api/v1/user", PathItem::new( HttpMethod::Get, - Operation::builder().response("200", Response::new("This will not get added")), + Operation::builder() + .response("200", Response::new("This will not get added")), ), ) .path( "/api/v1/user", PathItem::new( HttpMethod::Post, - Operation::builder().response("200", Response::new("Post user success 1")), + Operation::builder() + .response("200", Response::new("Post user success 1")), ), ) .path( "/api/v2/user", PathItem::new( HttpMethod::Get, - Operation::builder().response("200", Response::new("Get user success 2")), + Operation::builder() + .response("200", Response::new("Get user success 2")), ), ) .path( "/api/v2/user", PathItem::new( HttpMethod::Post, - Operation::builder().response("200", Response::new("Post user success 2")), + Operation::builder() + .response("200", Response::new("Post user success 2")), ), ) .extensions(Extensions::from_iter([("x-random", "Value")])), @@ -630,7 +653,10 @@ mod tests { let api = OpenApi::builder() .paths(Paths::builder().path( "/api/v1/status", - PathItem::new(HttpMethod::Get, Operation::builder().description("Get status")), + PathItem::new( + HttpMethod::Get, + Operation::builder().description("Get status"), + ), )) .build(); @@ -639,15 +665,23 @@ mod tests { Paths::builder() .path( "/", - PathItem::new(HttpMethod::Get, Operation::builder().description("Get user details").build()), + PathItem::new( + HttpMethod::Get, + Operation::builder().description("Get user details").build(), + ), ) - .path("/foo", PathItem::new(HttpMethod::Post, Operation::builder().build())), + .path( + "/foo", + PathItem::new(HttpMethod::Post, Operation::builder().build()), + ), ) .build(); let nest_merged = api.nest("/api/v1/user", user_api); let value = serde_json::to_value(nest_merged).expect("should serialize as json"); - let paths = value.pointer("/paths").expect("paths should exits in openapi"); + let paths = value + .pointer("/paths") + .expect("paths should exits in openapi"); assert_json_snapshot!(paths); } diff --git a/openapiv3_1/src/link.rs b/openapiv3_1/src/link.rs index d075b30..374b603 100644 --- a/openapiv3_1/src/link.rs +++ b/openapiv3_1/src/link.rs @@ -79,14 +79,23 @@ impl LinkBuilder { /// Add parameters to be passed to [Operation][operation] upon execution. /// /// [operation]: ../path/struct.Operation.html - pub fn parameters, V: Into>(self, items: impl IntoIterator) -> Self { - items.into_iter().fold(self, |this, (n, v)| this.parameter(n, v)) + pub fn parameters, V: Into>( + self, + items: impl IntoIterator, + ) -> Self { + items + .into_iter() + .fold(self, |this, (n, v)| this.parameter(n, v)) } /// Add parameter to be passed to [Operation][operation] upon execution. /// /// [operation]: ../path/struct.Operation.html - pub fn parameter, V: Into>(mut self, name: N, value: V) -> Self { + pub fn parameter, V: Into>( + mut self, + name: N, + value: V, + ) -> Self { self.parameters.insert(name.into(), value.into()); self } diff --git a/openapiv3_1/src/path.rs b/openapiv3_1/src/path.rs index 1d43d4f..5018909 100644 --- a/openapiv3_1/src/path.rs +++ b/openapiv3_1/src/path.rs @@ -67,17 +67,23 @@ impl Paths { /// # let paths = Paths::new(); /// let operation = paths.get_path_operation("/api/v1/user", HttpMethod::Get); /// ``` - pub fn get_path_operation>(&self, path: P, http_method: HttpMethod) -> Option<&Operation> { - self.paths.get(path.as_ref()).and_then(|path| match http_method { - HttpMethod::Get => path.get.as_ref(), - HttpMethod::Put => path.put.as_ref(), - HttpMethod::Post => path.post.as_ref(), - HttpMethod::Delete => path.delete.as_ref(), - HttpMethod::Options => path.options.as_ref(), - HttpMethod::Head => path.head.as_ref(), - HttpMethod::Patch => path.patch.as_ref(), - HttpMethod::Trace => path.trace.as_ref(), - }) + pub fn get_path_operation>( + &self, + path: P, + http_method: HttpMethod, + ) -> Option<&Operation> { + self.paths + .get(path.as_ref()) + .and_then(|path| match http_method { + HttpMethod::Get => path.get.as_ref(), + HttpMethod::Put => path.put.as_ref(), + HttpMethod::Post => path.post.as_ref(), + HttpMethod::Delete => path.delete.as_ref(), + HttpMethod::Options => path.options.as_ref(), + HttpMethod::Head => path.head.as_ref(), + HttpMethod::Patch => path.patch.as_ref(), + HttpMethod::Trace => path.trace.as_ref(), + }) } /// Append path operation to the list of paths. @@ -109,8 +115,10 @@ impl Paths { }; } } else { - self.paths - .insert(String::from(path), PathItem::from_http_methods(http_methods, operation)); + self.paths.insert( + String::from(path), + PathItem::from_http_methods(http_methods, operation), + ); } } @@ -150,7 +158,10 @@ impl PathsBuilder { /// Append [`PathItem`]s with path to map of paths. If path already exists it will merge [`Operation`]s of /// [`PathItem`] with already found path item operations. - pub fn paths, P: Into>(self, items: impl IntoIterator) -> Self { + pub fn paths, P: Into>( + self, + items: impl IntoIterator, + ) -> Self { items.into_iter().fold(self, |this, (i, p)| this.path(i, p)) } } @@ -253,7 +264,10 @@ impl PathItem { } /// Constructs a new [`PathItem`] with given [`Operation`] set for provided [`HttpMethod`]s. - pub fn from_http_methods, O: Into>(http_methods: I, operation: O) -> Self { + pub fn from_http_methods, O: Into>( + http_methods: I, + operation: O, + ) -> Self { let mut path_item = Self::default(); let operation = operation.into(); for method in http_methods { @@ -447,26 +461,41 @@ impl OperationBuilder { /// Add or change parameters of the [`Operation`]. pub fn parameters>(self, parameters: impl IntoIterator) -> Self { - parameters.into_iter().fold(self, |this, p| this.parameter(p)) + parameters + .into_iter() + .fold(self, |this, p| this.parameter(p)) } /// Append parameter to [`Operation`] parameters. pub fn parameter(mut self, parameter: impl Into) -> Self { - self.parameters.get_or_insert_default().push(parameter.into()); + self.parameters + .get_or_insert_default() + .push(parameter.into()); self } /// Add or change responses of the [`Operation`]. - pub fn responses>, C: Into>(self, responses: impl IntoIterator) -> Self { - responses.into_iter().fold(self, |this, (c, r)| this.response(c, r)) + pub fn responses>, C: Into>( + self, + responses: impl IntoIterator, + ) -> Self { + responses + .into_iter() + .fold(self, |this, (c, r)| this.response(c, r)) } /// Append status code and a [`Response`] to the [`Operation`] responses map. /// /// * `code` must be valid HTTP status code. /// * `response` is instances of [`Response`]. - pub fn response(mut self, code: impl Into, response: impl Into>) -> Self { - self.responses.responses.insert(code.into(), response.into()); + pub fn response( + mut self, + code: impl Into, + response: impl Into>, + ) -> Self { + self.responses + .responses + .insert(code.into(), response.into()); self } @@ -478,8 +507,13 @@ impl OperationBuilder { } /// Append [`SecurityRequirement`] to [`Operation`] security requirements. - pub fn securities>(self, securities: impl IntoIterator) -> Self { - securities.into_iter().fold(self, |this, s| this.security(s)) + pub fn securities>( + self, + securities: impl IntoIterator, + ) -> Self { + securities + .into_iter() + .fold(self, |this, s| this.security(s)) } /// Append [`Server`]s to the [`Operation`]. @@ -507,13 +541,20 @@ impl Operation { } /// Add or change parameters of the [`Operation`]. - pub fn parameters>(&mut self, parameters: impl IntoIterator) -> &mut Self { - parameters.into_iter().fold(self, |this, p| this.parameter(p)) + pub fn parameters>( + &mut self, + parameters: impl IntoIterator, + ) -> &mut Self { + parameters + .into_iter() + .fold(self, |this, p| this.parameter(p)) } /// Append parameter to [`Operation`] parameters. pub fn parameter(&mut self, parameter: impl Into) -> &mut Self { - self.parameters.get_or_insert_default().push(parameter.into()); + self.parameters + .get_or_insert_default() + .push(parameter.into()); self } @@ -522,15 +563,23 @@ impl Operation { &mut self, responses: impl IntoIterator, ) -> &mut Self { - responses.into_iter().fold(self, |this, (c, r)| this.response(c, r)) + responses + .into_iter() + .fold(self, |this, (c, r)| this.response(c, r)) } /// Append status code and a [`Response`] to the [`Operation`] responses map. /// /// * `code` must be valid HTTP status code. /// * `response` is instances of [`Response`]. - pub fn response(&mut self, code: impl Into, response: impl Into>) -> &mut Self { - self.responses.responses.insert(code.into(), response.into()); + pub fn response( + &mut self, + code: impl Into, + response: impl Into>, + ) -> &mut Self { + self.responses + .responses + .insert(code.into(), response.into()); self } @@ -542,8 +591,13 @@ impl Operation { } /// Append [`SecurityRequirement`] to [`Operation`] security requirements. - pub fn securities>(&mut self, securities: impl IntoIterator) -> &mut Self { - securities.into_iter().fold(self, |this, s| this.security(s)) + pub fn securities>( + &mut self, + securities: impl IntoIterator, + ) -> &mut Self { + securities + .into_iter() + .fold(self, |this, s| this.security(s)) } /// Append [`Server`]s to the [`Operation`]. @@ -658,7 +712,6 @@ pub enum ParameterIn { Cookie, } - /// Defines how [`Parameter`] should be serialized. #[derive(Serialize, Deserialize, Clone, PartialEq, Eq)] #[cfg_attr(feature = "debug", derive(Debug))] @@ -704,17 +757,30 @@ mod tests { let paths_list = Paths::builder() .path("/todo", PathItem::new(HttpMethod::Get, Operation::new())) .path("/todo", PathItem::new(HttpMethod::Post, Operation::new())) - .path("/todo/{id}", PathItem::new(HttpMethod::Delete, Operation::new())) - .path("/todo/{id}", PathItem::new(HttpMethod::Get, Operation::new())) - .path("/todo/{id}", PathItem::new(HttpMethod::Put, Operation::new())) - .path("/todo/search", PathItem::new(HttpMethod::Get, Operation::new())) + .path( + "/todo/{id}", + PathItem::new(HttpMethod::Delete, Operation::new()), + ) + .path( + "/todo/{id}", + PathItem::new(HttpMethod::Get, Operation::new()), + ) + .path( + "/todo/{id}", + PathItem::new(HttpMethod::Put, Operation::new()), + ) + .path( + "/todo/search", + PathItem::new(HttpMethod::Get, Operation::new()), + ) .build(); let actual_value = paths_list .paths .iter() .flat_map(|(path, path_item)| { - let mut path_methods = Vec::<(&str, &HttpMethod)>::with_capacity(paths_list.paths.len()); + let mut path_methods = + Vec::<(&str, &HttpMethod)>::with_capacity(paths_list.paths.len()); if path_item.get.is_some() { path_methods.push((path, &HttpMethod::Get)); } @@ -780,7 +846,8 @@ mod tests { #[test] fn operation_builder_security() { - let security_requirement1 = SecurityRequirement::new("api_oauth2_flow", ["edit:items", "read:items"]); + let security_requirement1 = + SecurityRequirement::new("api_oauth2_flow", ["edit:items", "read:items"]); let security_requirement2 = SecurityRequirement::new("api_oauth2_flow", ["remove:items"]); let operation = Operation::builder() .security(security_requirement1) diff --git a/openapiv3_1/src/request_body.rs b/openapiv3_1/src/request_body.rs index 0ef655f..43a502c 100644 --- a/openapiv3_1/src/request_body.rs +++ b/openapiv3_1/src/request_body.rs @@ -48,8 +48,13 @@ impl RequestBodyBuilder { } /// Add [`Content`] by content type e.g `application/json` to [`RequestBody`]. - pub fn contents, C: Into>(self, contents: impl IntoIterator) -> Self { - contents.into_iter().fold(self, |this, (t, c)| this.content(t, c)) + pub fn contents, C: Into>( + self, + contents: impl IntoIterator, + ) -> Self { + contents + .into_iter() + .fold(self, |this, (t, c)| this.content(t, c)) } } @@ -81,7 +86,10 @@ mod tests { let request_body = RequestBody::builder() .description("A sample requestBody") .required(true) - .content("application/json", Content::new(Some(Ref::from_schema_name("EmailPayload")))) + .content( + "application/json", + Content::new(Some(Ref::from_schema_name("EmailPayload"))), + ) .build(); assert_json_snapshot!(request_body); } diff --git a/openapiv3_1/src/response.rs b/openapiv3_1/src/response.rs index 60aff38..97c60f2 100644 --- a/openapiv3_1/src/response.rs +++ b/openapiv3_1/src/response.rs @@ -40,19 +40,29 @@ impl Responses { impl ResponsesBuilder { /// Add a [`Response`]. - pub fn response(mut self, code: impl Into, response: impl Into>) -> Self { + pub fn response( + mut self, + code: impl Into, + response: impl Into>, + ) -> Self { self.responses.insert(code.into(), response.into()); self } /// Add responses from an iterator over a pair of `(status_code, response): (String, Response)`. - pub fn responses_from_iter, C: Into, R: Into>>( + pub fn responses_from_iter< + I: IntoIterator, + C: Into, + R: Into>, + >( mut self, iter: I, ) -> Self { - self.responses - .extend(iter.into_iter().map(|(code, response)| (code.into(), response.into()))); + self.responses.extend( + iter.into_iter() + .map(|(code, response)| (code.into(), response.into())), + ); self } } @@ -70,7 +80,10 @@ where { fn from_iter>(iter: T) -> Self { Self { - responses: IndexMap::from_iter(iter.into_iter().map(|(code, response)| (code.into(), response.into()))), + responses: IndexMap::from_iter( + iter.into_iter() + .map(|(code, response)| (code.into(), response.into())), + ), ..Default::default() } } @@ -146,17 +159,30 @@ impl ResponseBuilder { } /// Add [`Content`] of the [`Response`] with content type e.g `application/json`. - pub fn contents, B: Into>(self, contents: impl IntoIterator) -> Self { - contents.into_iter().fold(self, |this, (a, b)| this.content(a, b)) + pub fn contents, B: Into>( + self, + contents: impl IntoIterator, + ) -> Self { + contents + .into_iter() + .fold(self, |this, (a, b)| this.content(a, b)) } /// Add response [`Header`]. - pub fn headers, B: Into
>(self, headers: impl IntoIterator) -> Self { - headers.into_iter().fold(self, |this, (a, b)| this.header(a, b)) + pub fn headers, B: Into
>( + self, + headers: impl IntoIterator, + ) -> Self { + headers + .into_iter() + .fold(self, |this, (a, b)| this.header(a, b)) } /// Add link that can be followed from the response. - pub fn links, B: Into>>(self, links: impl IntoIterator) -> Self { + pub fn links, B: Into>>( + self, + links: impl IntoIterator, + ) -> Self { links.into_iter().fold(self, |this, (a, b)| this.link(a, b)) } } diff --git a/openapiv3_1/src/schema.rs b/openapiv3_1/src/schema.rs index 708d226..5d4203d 100644 --- a/openapiv3_1/src/schema.rs +++ b/openapiv3_1/src/schema.rs @@ -70,7 +70,9 @@ pub struct Components { impl Components { /// Construct a new [`Components`]. pub fn new() -> Self { - Self { ..Default::default() } + Self { + ..Default::default() + } } /// Add [`SecurityScheme`] to [`Components`]. @@ -78,8 +80,13 @@ impl Components { /// Accepts two arguments where first is the name of the [`SecurityScheme`]. This is later when /// referenced by [`SecurityRequirement`]s. Second parameter is the [`SecurityScheme`]. /// - pub fn add_security_scheme, S: Into>(&mut self, name: N, security_scheme: S) { - self.security_schemes.insert(name.into(), security_scheme.into()); + pub fn add_security_scheme, S: Into>( + &mut self, + name: N, + security_scheme: S, + ) { + self.security_schemes + .insert(name.into(), security_scheme.into()); } /// Add iterator of [`SecurityScheme`]s to [`Components`]. @@ -90,8 +97,11 @@ impl Components { &mut self, schemas: impl IntoIterator, ) { - self.security_schemes - .extend(schemas.into_iter().map(|(name, item)| (name.into(), item.into()))); + self.security_schemes.extend( + schemas + .into_iter() + .map(|(name, item)| (name.into(), item.into())), + ); } /// Add [`Schema`] to [`Components`]. @@ -108,9 +118,15 @@ impl Components { /// referenced by [`Ref::ref_location`]s. Second parameter is the [`Schema`]. /// /// [requirement]: ../security/struct.SecurityRequirement.html - pub fn add_schemas_from_iter, S: Into>(&mut self, schemas: impl IntoIterator) { - self.schemas - .extend(schemas.into_iter().map(|(name, item)| (name.into(), item.into()))); + pub fn add_schemas_from_iter, S: Into>( + &mut self, + schemas: impl IntoIterator, + ) { + self.schemas.extend( + schemas + .into_iter() + .map(|(name, item)| (name.into(), item.into())), + ); } } @@ -144,8 +160,11 @@ impl ComponentsBuilder { mut self, schemas: I, ) -> Self { - self.schemas - .extend(schemas.into_iter().map(|(name, schema)| (name.into(), schema.into()))); + self.schemas.extend( + schemas + .into_iter() + .map(|(name, schema)| (name.into(), schema.into())), + ); self } @@ -154,7 +173,11 @@ impl ComponentsBuilder { /// /// Method accepts tow arguments; `name` of the reusable response and `response` which is the /// reusable response itself. - pub fn response, R: Into>>(mut self, name: S2, response: R) -> Self { + pub fn response, R: Into>>( + mut self, + name: S2, + response: R, + ) -> Self { self.responses.insert(name.into(), response.into()); self } @@ -163,12 +186,19 @@ impl ComponentsBuilder { /// /// Like the [`ComponentsBuilder::schemas_from_iter`] this allows adding multiple responses by /// any iterator what returns tuples of (name, response) values. - pub fn responses_from_iter, S2: Into, R: Into>>( + pub fn responses_from_iter< + I: IntoIterator, + S2: Into, + R: Into>, + >( mut self, responses: I, ) -> Self { - self.responses - .extend(responses.into_iter().map(|(name, response)| (name.into(), response.into()))); + self.responses.extend( + responses + .into_iter() + .map(|(name, response)| (name.into(), response.into())), + ); self } @@ -179,8 +209,13 @@ impl ComponentsBuilder { /// referenced by [`SecurityRequirement`][requirement]s. Second parameter is the [`SecurityScheme`]. /// /// [requirement]: ../security/struct.SecurityRequirement.html - pub fn security_scheme, S2: Into>(mut self, name: N, security_scheme: S2) -> Self { - self.security_schemes.insert(name.into(), security_scheme.into()); + pub fn security_scheme, S2: Into>( + mut self, + name: N, + security_scheme: S2, + ) -> Self { + self.security_schemes + .insert(name.into(), security_scheme.into()); self } @@ -257,13 +292,22 @@ impl Discriminator { /// ("cat","#/components/schemas/Cat") /// ]); /// ``` - pub fn with_mapping, M: IntoIterator, K: Into, V: Into>( + pub fn with_mapping< + P: Into, + M: IntoIterator, + K: Into, + V: Into, + >( property_name: P, mapping: M, ) -> Self { Self { property_name: property_name.into(), - mapping: IndexMap::from_iter(mapping.into_iter().map(|(key, val)| (key.into(), val.into()))), + mapping: IndexMap::from_iter( + mapping + .into_iter() + .map(|(key, val)| (key.into(), val.into())), + ), ..Default::default() } } @@ -607,7 +651,10 @@ pub struct Object { pub min_contains: Option, /// The `additionalProperties` keyword defines the schema for object properties not explicitly listed. /// - #[serde(rename = "additionalProperties", skip_serializing_if = "Option::is_none")] + #[serde( + rename = "additionalProperties", + skip_serializing_if = "Option::is_none" + )] #[is_empty(if = "is_empty::is_option_really_empty")] pub additional_properties: Option, /// The `definitions` section holds reusable schema definitions for reference. @@ -618,7 +665,10 @@ pub struct Object { pub definitions: IndexMap, /// The `patternProperties` keyword maps regex patterns to schemas for matching property names. /// - #[serde(rename = "patternProperties", skip_serializing_if = "IndexMap::is_empty")] + #[serde( + rename = "patternProperties", + skip_serializing_if = "IndexMap::is_empty" + )] #[builder(default)] #[is_empty(if = "IndexMap::is_empty")] pub pattern_properties: IndexMap, @@ -692,7 +742,10 @@ pub struct Object { pub unevaluated_items: Option, /// The `unevaluatedProperties` keyword applies schemas to properties not covered by `properties` or pattern-based keywords. /// - #[serde(rename = "unevaluatedProperties", skip_serializing_if = "Option::is_none")] + #[serde( + rename = "unevaluatedProperties", + skip_serializing_if = "Option::is_none" + )] #[is_empty(if = "is_empty::is_option_really_empty")] pub unevaluated_properties: Option, /// The `discriminator` keyword provides object property-based type differentiation (OpenAPI). @@ -718,7 +771,10 @@ impl From for Object { impl ObjectBuilder { /// Extend the properties using the iterator of `(name, schema)` - pub fn properties, C: Into>(mut self, properties: impl IntoIterator) -> Self { + pub fn properties, C: Into>( + mut self, + properties: impl IntoIterator, + ) -> Self { self.properties .extend(properties.into_iter().map(|(p, s)| (p.into(), s.into()))); self @@ -766,13 +822,20 @@ impl ObjectBuilder { /// Add a singular item into the `enum` array pub fn enum_value(mut self, enum_value: impl Into) -> Self { - self.enum_values.get_or_insert_default().push(enum_value.into()); + self.enum_values + .get_or_insert_default() + .push(enum_value.into()); self } /// Extend the `enum` array using an iterator of items - pub fn enum_values>(self, enum_values: impl IntoIterator) -> Self { - enum_values.into_iter().fold(self, |this, e| this.enum_value(e)) + pub fn enum_values>( + self, + enum_values: impl IntoIterator, + ) -> Self { + enum_values + .into_iter() + .fold(self, |this, e| this.enum_value(e)) } /// Add a single field into the `required` array @@ -793,14 +856,19 @@ impl ObjectBuilder { } /// Extend the `examples` array using an iterator of examples. - pub fn examples>(self, examples: impl IntoIterator) -> Self { + pub fn examples>( + self, + examples: impl IntoIterator, + ) -> Self { examples.into_iter().fold(self, |this, e| this.example(e)) } } impl ObjectBuilder { /// Convert the object into an array of this type - pub fn to_array(self) -> ObjectBuilder> { + pub fn to_array( + self, + ) -> ObjectBuilder> { Object::builder().schema_type(Type::Array).items(self) } } @@ -959,7 +1027,10 @@ impl Object { schema.optimize(); } - self.all_of = all_ofs.into_iter().filter(|schema| !schema.is_empty()).collect(); + self.all_of = all_ofs + .into_iter() + .filter(|schema| !schema.is_empty()) + .collect(); dedupe_array(&mut self.examples); dedupe_array(&mut self.required); if let Some(_enum) = &mut self.enum_values { @@ -1185,14 +1256,20 @@ fn merge_array_union(value: &mut Vec, other: &mut Vec) { value.retain(|v| other.contains(v)); } -fn merge_array_union_optional(value: &mut Option>, other: &mut Option>) { +fn merge_array_union_optional( + value: &mut Option>, + other: &mut Option>, +) { merge_array_union(value.as_mut().unwrap(), other.as_mut().unwrap()); if other.as_ref().is_some_and(|o| o.is_empty()) { other.take(); } } -fn merge_array_combine_optional(value: &mut Option>, other: &mut Option>) { +fn merge_array_combine_optional( + value: &mut Option>, + other: &mut Option>, +) { merge_array_combine(value.as_mut().unwrap(), other.as_mut().unwrap()); if other.as_ref().is_some_and(|o| o.is_empty()) { other.take(); @@ -1226,7 +1303,8 @@ fn merge_type(value: &mut Option, other: &mut Option) { (Types::Multi(s), Types::Multi(ref mut o)) => { merge_array_union(s, o); } - (&mut Types::Single(s), Types::Multi(ref o)) | (&mut Types::Multi(ref o), Types::Single(s)) => { + (&mut Types::Single(s), Types::Multi(ref o)) + | (&mut Types::Multi(ref o), Types::Single(s)) => { if o.contains(&s) { value.replace(Types::Single(s)); } else { @@ -1408,7 +1486,9 @@ mod tests { ) .property( "name", - Object::builder().schema_type(Type::String).description("Name of credential"), + Object::builder() + .schema_type(Type::String) + .description("Name of credential"), ) .property( "status", @@ -1418,8 +1498,17 @@ mod tests { .description("Credential status") .enum_values(["Active", "NotActive", "Locked", "Expired"]), ) - .property("history", Schema::from(Ref::from_schema_name("UpdateHistory")).to_array()) - .property("tags", Object::builder().schema_type(Type::String).build().to_array()), + .property( + "history", + Schema::from(Ref::from_schema_name("UpdateHistory")).to_array(), + ) + .property( + "tags", + Object::builder() + .schema_type(Type::String) + .build() + .to_array(), + ), ), ) .build(), @@ -1452,7 +1541,12 @@ mod tests { let id = credential.get("id").unwrap().as_object().unwrap(); assert_eq!( - id.get("default").unwrap().as_number().unwrap().as_i64().unwrap(), + id.get("default") + .unwrap() + .as_number() + .unwrap() + .as_i64() + .unwrap(), 1, "components.schemas.Credential.properties.id.default did not match" ); @@ -1541,7 +1635,9 @@ mod tests { ) .property( "name", - Object::builder().schema_type(Type::String).description("Name of credential"), + Object::builder() + .schema_type(Type::String) + .description("Name of credential"), ) .property( "status", @@ -1551,8 +1647,14 @@ mod tests { .description("Credential status") .enum_values(["Active", "NotActive", "Locked", "Expired"]), ) - .property("history", Schema::from(Ref::from_schema_name("UpdateHistory")).to_array()) - .property("tags", Object::builder().schema_type(Type::String).to_array()) + .property( + "history", + Schema::from(Ref::from_schema_name("UpdateHistory")).to_array(), + ) + .property( + "tags", + Object::builder().schema_type(Type::String).to_array(), + ) .build(); assert_eq!( @@ -1610,7 +1712,10 @@ mod tests { #[test] fn test_object_with_title() { - let json_value = Object::builder().schema_type(Type::Object).title("SomeName").build(); + let json_value = Object::builder() + .schema_type(Type::Object) + .title("SomeName") + .build(); assert_json_snapshot!(json_value, @r#" { "title": "SomeName", @@ -1658,7 +1763,10 @@ mod tests { .to_array() .build(); - assert!(matches!(array.schema_type, Some(Types::Single(Type::Array)))); + assert!(matches!( + array.schema_type, + Some(Types::Single(Type::Array)) + )); } #[test] @@ -1677,7 +1785,10 @@ mod tests { ) .build(); - assert!(matches!(array.schema_type, Some(Types::Single(Type::Array)))); + assert!(matches!( + array.schema_type, + Some(Types::Single(Type::Array)) + )); } #[test] @@ -1691,7 +1802,10 @@ mod tests { .required(["name"]), ), )]) - .responses_from_iter(vec![("200", Response::builder().description("Okay").build())]) + .responses_from_iter(vec![( + "200", + Response::builder().description("Okay").build(), + )]) .security_scheme( "TLS", SecurityScheme::MutualTls { @@ -1703,7 +1817,8 @@ mod tests { let serialized_components = serde_json::to_string(&components).unwrap(); - let deserialized_components: Components = serde_json::from_str(serialized_components.as_str()).unwrap(); + let deserialized_components: Components = + serde_json::from_str(serialized_components.as_str()).unwrap(); assert_eq!( serialized_components, @@ -1719,7 +1834,8 @@ mod tests { .build(); let serialized_components = serde_json::to_string(&prop).unwrap(); - let deserialized_components: Object = serde_json::from_str(serialized_components.as_str()).unwrap(); + let deserialized_components: Object = + serde_json::from_str(serialized_components.as_str()).unwrap(); assert_eq!( serialized_components, @@ -1732,7 +1848,8 @@ mod tests { let prop = Object::builder().schema_type(Type::String).build(); let serialized_components = serde_json::to_string(&prop).unwrap(); - let deserialized_components: Object = serde_json::from_str(serialized_components.as_str()).unwrap(); + let deserialized_components: Object = + serde_json::from_str(serialized_components.as_str()).unwrap(); assert_eq!( serialized_components, @@ -1765,8 +1882,13 @@ mod tests { "test", Object::builder() .any_ofs([ - Object::builder().property("element", Ref::new("#/test")).build().to_array(), - Object::builder().property("foobar", Ref::new("#/foobar")).build(), + Object::builder() + .property("element", Ref::new("#/test")) + .build() + .to_array(), + Object::builder() + .property("foobar", Ref::new("#/foobar")) + .build(), ]) .build(), ) @@ -1808,7 +1930,10 @@ mod tests { #[test] fn serialize_deserialize_schema_array_builder() { - let ref_or_schema = Object::builder().property("element", Ref::new("#/test")).build().to_array(); + let ref_or_schema = Object::builder() + .property("element", Ref::new("#/test")) + .build() + .to_array(); let json_str = serde_json::to_string(&ref_or_schema).expect(""); println!("----------------------------"); @@ -1847,8 +1972,9 @@ mod tests { let schema = Object::builder() .property( "map", - Object::builder() - .additional_properties(Object::builder().property("name", Object::builder().schema_type(Type::String))), + Object::builder().additional_properties( + Object::builder().property("name", Object::builder().schema_type(Type::String)), + ), ) .build(); @@ -1894,7 +2020,9 @@ mod tests { #[test] fn serialize_deserialize_object_with_multiple_schema_types() { - let object = Object::builder().schema_type(vec![Type::Object, Type::Null]).build(); + let object = Object::builder() + .schema_type(vec![Type::Object, Type::Null]) + .build(); let json_str = serde_json::to_string(&object).unwrap(); println!("----------------------------"); @@ -1912,7 +2040,8 @@ mod tests { #[test] fn object_with_extensions() { let expected = json!("value"); - let extensions = extensions::Extensions::default().add("x-some-extension", expected.clone()); + let extensions = + extensions::Extensions::default().add("x-some-extension", expected.clone()); let json_value = Object::builder().extensions(extensions).build(); let value = serde_json::to_value(&json_value).unwrap(); @@ -1922,7 +2051,8 @@ mod tests { #[test] fn array_with_extensions() { let expected = json!("value"); - let extensions = extensions::Extensions::default().add("x-some-extension", expected.clone()); + let extensions = + extensions::Extensions::default().add("x-some-extension", expected.clone()); let json_value = Object::builder().extensions(extensions).to_array().build(); let value = serde_json::to_value(&json_value).unwrap(); @@ -1932,7 +2062,8 @@ mod tests { #[test] fn oneof_with_extensions() { let expected = json!("value"); - let extensions = extensions::Extensions::default().add("x-some-extension", expected.clone()); + let extensions = + extensions::Extensions::default().add("x-some-extension", expected.clone()); let json_value = Object::builder() .one_of(Object::builder().extensions(extensions).build()) .build(); @@ -1944,7 +2075,8 @@ mod tests { #[test] fn allof_with_extensions() { let expected = json!("value"); - let extensions = extensions::Extensions::default().add("x-some-extension", expected.clone()); + let extensions = + extensions::Extensions::default().add("x-some-extension", expected.clone()); let json_value = Object::builder() .all_of(Object::builder().extensions(extensions).build()) .build(); @@ -1956,7 +2088,8 @@ mod tests { #[test] fn anyof_with_extensions() { let expected = json!("value"); - let extensions = extensions::Extensions::default().add("x-some-extension", expected.clone()); + let extensions = + extensions::Extensions::default().add("x-some-extension", expected.clone()); let json_value = Object::builder() .any_of(Object::builder().extensions(extensions).build()) .build(); @@ -2081,7 +2214,10 @@ mod tests { let not_format_a = Schema::object( Object::builder() .not(Schema::object( - Object::builder().schema_type(Type::String).format("email").build(), + Object::builder() + .schema_type(Type::String) + .format("email") + .build(), )) .build(), ); @@ -2089,7 +2225,10 @@ mod tests { let not_format_b = Schema::object( Object::builder() .not(Schema::object( - Object::builder().schema_type(Type::String).format("date-time").build(), + Object::builder() + .schema_type(Type::String) + .format("date-time") + .build(), )) .build(), ); @@ -2097,7 +2236,10 @@ mod tests { let not_format_c = Schema::object( Object::builder() .not(Schema::object( - Object::builder().schema_type(Type::String).format("ipv4").build(), + Object::builder() + .schema_type(Type::String) + .format("ipv4") + .build(), )) .build(), ); diff --git a/openapiv3_1/src/security.rs b/openapiv3_1/src/security.rs index 95bc613..c9f6c48 100644 --- a/openapiv3_1/src/security.rs +++ b/openapiv3_1/src/security.rs @@ -51,7 +51,10 @@ impl SecurityRequirement { /// /// If you have more than one name in the security requirement you can use /// [`SecurityRequirement::add`]. - pub fn new, S: IntoIterator, I: Into>(name: N, scopes: S) -> Self { + pub fn new, S: IntoIterator, I: Into>( + name: N, + scopes: S, + ) -> Self { Self { value: IndexMap::from_iter(iter::once_with(|| { ( @@ -70,7 +73,11 @@ impl SecurityRequirement { /// Accepts name for the security requirement which must match to the name of available [`SecurityScheme`]. /// Second parameter is [`IntoIterator`] of [`Into`] scopes needed by the [`SecurityRequirement`]. /// Scopes must match to the ones defined in [`SecurityScheme`]. - pub fn add, S: IntoIterator, I: Into>(mut self, name: N, scopes: S) -> Self { + pub fn add, S: IntoIterator, I: Into>( + mut self, + name: N, + scopes: S, + ) -> Self { self.value.insert( Into::::into(name), scopes.into_iter().map(Into::::into).collect(), @@ -274,7 +281,6 @@ pub enum HttpAuthScheme { Vapid, } - /// Open id connect [`SecurityScheme`]. #[non_exhaustive] #[derive(Serialize, Deserialize, Clone, PartialEq, Eq)] @@ -415,7 +421,10 @@ impl OAuth2 { /// ), /// ], "my oauth2 flow"); /// ``` - pub fn with_description, S: Into>(flows: I, description: S) -> Self { + pub fn with_description, S: Into>( + flows: I, + description: S, + ) -> Self { Self { flows: IndexMap::from_iter( flows @@ -533,7 +542,11 @@ impl Implicit { /// "https://localhost/refresh-token" /// ); /// ``` - pub fn with_refresh_url>(authorization_url: S, scopes: Scopes, refresh_url: S) -> Self { + pub fn with_refresh_url>( + authorization_url: S, + scopes: Scopes, + refresh_url: S, + ) -> Self { Self { authorization_url: authorization_url.into(), refresh_url: Some(refresh_url.into()), @@ -597,7 +610,11 @@ impl AuthorizationCode { /// Scopes::new(), /// ); /// ``` - pub fn new, T: Into>(authorization_url: A, token_url: T, scopes: Scopes) -> Self { + pub fn new, T: Into>( + authorization_url: A, + token_url: T, + scopes: Scopes, + ) -> Self { Self { authorization_url: authorization_url.into(), token_url: token_url.into(), @@ -624,7 +641,12 @@ impl AuthorizationCode { /// "https://localhost/refresh-token" /// ); /// ``` - pub fn with_refresh_url>(authorization_url: S, token_url: S, scopes: Scopes, refresh_url: S) -> Self { + pub fn with_refresh_url>( + authorization_url: S, + token_url: S, + scopes: Scopes, + refresh_url: S, + ) -> Self { Self { authorization_url: authorization_url.into(), token_url: token_url.into(), @@ -860,7 +882,9 @@ impl Scopes { /// let scopes = Scopes::new(); /// ``` pub fn new() -> Self { - Self { ..Default::default() } + Self { + ..Default::default() + } } /// Construct new [`Scopes`] with holding one scope. @@ -888,7 +912,10 @@ where { fn from_iter>(iter: T) -> Self { Self { - scopes: iter.into_iter().map(|(key, value)| (key.into(), value.into())).collect(), + scopes: iter + .into_iter() + .map(|(key, value)| (key.into(), value.into())) + .collect(), } } } diff --git a/openapiv3_1/src/server.rs b/openapiv3_1/src/server.rs index 0208f1a..2639e6b 100644 --- a/openapiv3_1/src/server.rs +++ b/openapiv3_1/src/server.rs @@ -53,7 +53,9 @@ use super::extensions::Extensions; /// /// [openapi]: ../struct.OpenApi.html #[non_exhaustive] -#[derive(serde_derive::Serialize, serde_derive::Deserialize, Default, Clone, PartialEq, Eq, bon::Builder)] +#[derive( + serde_derive::Serialize, serde_derive::Deserialize, Default, Clone, PartialEq, Eq, bon::Builder, +)] #[cfg_attr(feature = "debug", derive(Debug))] #[serde(rename_all = "camelCase")] #[builder(on(_, into))] @@ -115,8 +117,14 @@ impl ServerBuilder { /// `{username}` substitution then the name should be `username`. /// * `parameter` Use [`ServerVariableBuilder`] to define how the parameter is being substituted /// within the url. - pub fn parameter(mut self, name: impl Into, variable: impl Into) -> Self { - self.variables.get_or_insert_default().insert(name.into(), variable.into()); + pub fn parameter( + mut self, + name: impl Into, + variable: impl Into, + ) -> Self { + self.variables + .get_or_insert_default() + .insert(name.into(), variable.into()); self } } @@ -125,7 +133,9 @@ impl ServerBuilder { /// /// [server_variable]: https://spec.openapis.org/oas/latest.html#server-variable-object #[non_exhaustive] -#[derive(serde_derive::Serialize, serde_derive::Deserialize, Default, Clone, PartialEq, Eq, bon::Builder)] +#[derive( + serde_derive::Serialize, serde_derive::Deserialize, Default, Clone, PartialEq, Eq, bon::Builder, +)] #[cfg_attr(feature = "debug", derive(Debug))] #[builder(on(_, into))] pub struct ServerVariable { diff --git a/openapiv3_1/src/xml.rs b/openapiv3_1/src/xml.rs index 66e4880..2ae1f06 100644 --- a/openapiv3_1/src/xml.rs +++ b/openapiv3_1/src/xml.rs @@ -45,7 +45,9 @@ pub struct Xml { impl Xml { /// Construct a new [`Xml`] object. pub fn new() -> Self { - Self { ..Default::default() } + Self { + ..Default::default() + } } } diff --git a/postcompile/src/lib.rs b/postcompile/src/lib.rs index be155fb..18f0151 100644 --- a/postcompile/src/lib.rs +++ b/postcompile/src/lib.rs @@ -8,7 +8,10 @@ //! //! This is particularly useful when making snapshot tests of proc-macros, look //! below for an example with the `insta` crate. -#![cfg_attr(feature = "docs", doc = "\n\nSee the [changelog][changelog] for a full release history.")] +#![cfg_attr( + feature = "docs", + doc = "\n\nSee the [changelog][changelog] for a full release history." +)] #![cfg_attr(feature = "docs", doc = "## Feature flags")] #![cfg_attr(feature = "docs", doc = document_features::document_features!())] //! ## Usage @@ -214,7 +217,12 @@ fn cargo(config: &Config, manifest_path: &Path, subcommand: &str) -> Command { program.stderr(std::process::Stdio::piped()); program.stdout(std::process::Stdio::piped()); - let target_dir = if config.target_dir.as_ref().unwrap().ends_with(target_triple::TARGET) { + let target_dir = if config + .target_dir + .as_ref() + .unwrap() + .ends_with(target_triple::TARGET) + { config.target_dir.as_ref().unwrap().parent().unwrap() } else { config.target_dir.as_ref().unwrap() @@ -226,7 +234,11 @@ fn cargo(config: &Config, manifest_path: &Path, subcommand: &str) -> Command { if !cfg!(trybuild_no_target) && !cfg!(postcompile_no_target) - && config.target_dir.as_ref().unwrap().ends_with(target_triple::TARGET) + && config + .target_dir + .as_ref() + .unwrap() + .ends_with(target_triple::TARGET) { program.arg("--target").arg(target_triple::TARGET); } @@ -259,39 +271,53 @@ fn generate_cargo_toml(config: &Config, crate_name: &str) -> std::io::Result<(St .exec() .map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))?; - let workspace_manifest = cargo_manifest::Manifest::from_path(metadata.workspace_root.join("Cargo.toml")) - .map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))?; + let workspace_manifest = + cargo_manifest::Manifest::from_path(metadata.workspace_root.join("Cargo.toml")) + .map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))?; let manifest = cargo_manifest::Manifest:: { package: Some(cargo_manifest::Package { - publish: Some(cargo_manifest::MaybeInherited::Local(cargo_manifest::Publish::Flag(false))), + publish: Some(cargo_manifest::MaybeInherited::Local( + cargo_manifest::Publish::Flag(false), + )), edition: match config.edition.as_str() { - "2024" => Some(cargo_manifest::MaybeInherited::Local(cargo_manifest::Edition::E2024)), - "2021" => Some(cargo_manifest::MaybeInherited::Local(cargo_manifest::Edition::E2021)), - "2018" => Some(cargo_manifest::MaybeInherited::Local(cargo_manifest::Edition::E2018)), - "2015" => Some(cargo_manifest::MaybeInherited::Local(cargo_manifest::Edition::E2015)), + "2024" => Some(cargo_manifest::MaybeInherited::Local( + cargo_manifest::Edition::E2024, + )), + "2021" => Some(cargo_manifest::MaybeInherited::Local( + cargo_manifest::Edition::E2021, + )), + "2018" => Some(cargo_manifest::MaybeInherited::Local( + cargo_manifest::Edition::E2018, + )), + "2015" => Some(cargo_manifest::MaybeInherited::Local( + cargo_manifest::Edition::E2015, + )), _ => match metadata .packages .iter() .find(|p| p.name.as_ref() == config.package_name) .map(|p| p.edition) { - Some(cargo_metadata::Edition::E2015) => { - Some(cargo_manifest::MaybeInherited::Local(cargo_manifest::Edition::E2015)) - } - Some(cargo_metadata::Edition::E2018) => { - Some(cargo_manifest::MaybeInherited::Local(cargo_manifest::Edition::E2018)) - } - Some(cargo_metadata::Edition::E2021) => { - Some(cargo_manifest::MaybeInherited::Local(cargo_manifest::Edition::E2021)) - } - Some(cargo_metadata::Edition::E2024) => { - Some(cargo_manifest::MaybeInherited::Local(cargo_manifest::Edition::E2024)) - } + Some(cargo_metadata::Edition::E2015) => Some( + cargo_manifest::MaybeInherited::Local(cargo_manifest::Edition::E2015), + ), + Some(cargo_metadata::Edition::E2018) => Some( + cargo_manifest::MaybeInherited::Local(cargo_manifest::Edition::E2018), + ), + Some(cargo_metadata::Edition::E2021) => Some( + cargo_manifest::MaybeInherited::Local(cargo_manifest::Edition::E2021), + ), + Some(cargo_metadata::Edition::E2024) => Some( + cargo_manifest::MaybeInherited::Local(cargo_manifest::Edition::E2024), + ), _ => None, }, }, - ..cargo_manifest::Package::::new(crate_name.to_owned(), "0.1.0".into()) + ..cargo_manifest::Package::::new( + crate_name.to_owned(), + "0.1.0".into(), + ) }), workspace: Some(cargo_manifest::Workspace { default_members: None, @@ -326,7 +352,9 @@ fn generate_cargo_toml(config: &Config, crate_name: &str) -> std::io::Result<(St version: Some(version.clone()), ..Default::default() }, - cargo_manifest::Dependency::Inherited(_) => panic!("workspace deps cannot be inherited"), + cargo_manifest::Dependency::Inherited(_) => { + panic!("workspace deps cannot be inherited") + } }; if let Some(path) = dep.path.as_mut() @@ -363,9 +391,15 @@ fn generate_cargo_toml(config: &Config, crate_name: &str) -> std::io::Result<(St detail.version = Some(version); } - detail.features.get_or_insert_default().extend(dep.features.iter().cloned()); + detail + .features + .get_or_insert_default() + .extend(dep.features.iter().cloned()); - deps.insert(dep.name.clone(), cargo_manifest::Dependency::Detailed(detail)); + deps.insert( + dep.name.clone(), + cargo_manifest::Dependency::Detailed(detail), + ); } deps @@ -388,7 +422,8 @@ fn generate_cargo_toml(config: &Config, crate_name: &str) -> std::io::Result<(St }; Ok(( - toml::to_string(&manifest).map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))?, + toml::to_string(&manifest) + .map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))?, std::fs::read_to_string(metadata.workspace_root.join("Cargo.lock"))?, )) } @@ -397,7 +432,10 @@ static TEST_TIME_RE: std::sync::LazyLock = std::sync::LazyLock::new(|| regex::Regex::new(r"\d+\.\d+s").expect("failed to compile regex")); /// Compiles the given tokens and returns the output. -pub fn compile_custom(tokens: impl std::fmt::Display, config: &Config) -> std::io::Result { +pub fn compile_custom( + tokens: impl std::fmt::Display, + config: &Config, +) -> std::io::Result { let tokens = tokens.to_string(); if let Ok(deps_manifest) = std::env::var("POSTCOMPILE_DEPS_MANIFEST") { return manifest_mode(deps_manifest, config, tokens); @@ -428,12 +466,19 @@ pub fn compile_custom(tokens: impl std::fmt::Display, config: &Config) -> std::i let stdout = String::from_utf8(output.stdout).unwrap(); let syn_file = syn::parse_file(&stdout); - let stdout = syn_file.as_ref().map(prettyplease::unparse).unwrap_or(stdout); + let stdout = syn_file + .as_ref() + .map(prettyplease::unparse) + .unwrap_or(stdout); let cleanup_output = |out: &[u8]| { let out = String::from_utf8_lossy(out); let tmp_dir = config.tmp_dir.as_ref().unwrap().display().to_string(); - let main_relative = main_path.strip_prefix(&tmp_crate_path).unwrap().display().to_string(); + let main_relative = main_path + .strip_prefix(&tmp_crate_path) + .unwrap() + .display() + .to_string(); let main_path = main_path.display().to_string(); TEST_TIME_RE .replace_all(out.as_ref(), "[ELAPSED]s") @@ -476,7 +521,11 @@ pub fn compile_custom(tokens: impl std::fmt::Display, config: &Config) -> std::i Ok(result) } -fn manifest_mode(deps_manifest_path: String, config: &Config, tokens: String) -> std::io::Result { +fn manifest_mode( + deps_manifest_path: String, + config: &Config, + tokens: String, +) -> std::io::Result { let deps_manifest = match std::fs::read_to_string(&deps_manifest_path) { Ok(o) => o, Err(err) => panic!("error opening file: {deps_manifest_path} {err}"), @@ -490,13 +539,18 @@ fn manifest_mode(deps_manifest_path: String, config: &Config, tokens: String) -> let args: Vec<_> = manifest .direct .iter() - .map(|(name, file)| format!("--extern={name}={file}", file = current_dir.join(file).display())) - .chain( - manifest - .search - .iter() - .map(|search| format!("-Ldependency={search}", search = current_dir.join(search).display())), - ) + .map(|(name, file)| { + format!( + "--extern={name}={file}", + file = current_dir.join(file).display() + ) + }) + .chain(manifest.search.iter().map(|search| { + format!( + "-Ldependency={search}", + search = current_dir.join(search).display() + ) + })) .chain(manifest.extra_rustc_args.iter().cloned()) .chain([ "--crate-type=lib".into(), @@ -511,7 +565,8 @@ fn manifest_mode(deps_manifest_path: String, config: &Config, tokens: String) -> ]) .collect(); - let tmp_dir = std::env::var("TEST_TMPDIR").expect("TEST_TMPDIR must be set when using manifest mode."); + let tmp_dir = + std::env::var("TEST_TMPDIR").expect("TEST_TMPDIR must be set when using manifest mode."); let name = config.function_name.replace("::", "__"); let tmp_rs_path = Path::new(&tmp_dir).join(format!("{name}.rs")); write_tmp_file(&tokens, &tmp_rs_path); @@ -526,11 +581,18 @@ fn manifest_mode(deps_manifest_path: String, config: &Config, tokens: String) -> let stdout = String::from_utf8(output.stdout).unwrap(); let syn_file = syn::parse_file(&stdout); - let stdout = syn_file.as_ref().map(prettyplease::unparse).unwrap_or(stdout); + let stdout = syn_file + .as_ref() + .map(prettyplease::unparse) + .unwrap_or(stdout); let cleanup_output = |out: &[u8]| { let out = String::from_utf8_lossy(out); - let main_relative = tmp_rs_path.strip_prefix(&tmp_dir).unwrap().display().to_string(); + let main_relative = tmp_rs_path + .strip_prefix(&tmp_dir) + .unwrap() + .display() + .to_string(); let main_path = tmp_rs_path.display().to_string(); TEST_TIME_RE .replace_all(out.as_ref(), "[ELAPSED]s") diff --git a/tinc-build/src/codegen.rs b/tinc-build/src/codegen.rs index 7dd697f..96111e9 100644 --- a/tinc-build/src/codegen.rs +++ b/tinc-build/src/codegen.rs @@ -40,22 +40,40 @@ impl std::ops::DerefMut for Package { } } -pub(crate) fn generate_modules(registry: &ProtoTypeRegistry) -> anyhow::Result> { +pub(crate) fn generate_modules( + registry: &ProtoTypeRegistry, +) -> anyhow::Result> { let mut modules = BTreeMap::new(); registry .messages() .filter(|message| !registry.has_extern(&message.full_name)) - .try_for_each(|message| handle_message(message, modules.entry(message.package.clone()).or_default(), registry))?; + .try_for_each(|message| { + handle_message( + message, + modules.entry(message.package.clone()).or_default(), + registry, + ) + })?; registry .enums() .filter(|enum_| !registry.has_extern(&enum_.full_name)) - .try_for_each(|enum_| handle_enum(enum_, modules.entry(enum_.package.clone()).or_default(), registry))?; + .try_for_each(|enum_| { + handle_enum( + enum_, + modules.entry(enum_.package.clone()).or_default(), + registry, + ) + })?; - registry - .services() - .try_for_each(|service| handle_service(service, modules.entry(service.package.clone()).or_default(), registry))?; + registry.services().try_for_each(|service| { + handle_service( + service, + modules.entry(service.package.clone()).or_default(), + registry, + ) + })?; Ok(modules) } diff --git a/tinc-build/src/codegen/cel.rs b/tinc-build/src/codegen/cel.rs index ea958a6..3cd8319 100644 --- a/tinc-build/src/codegen/cel.rs +++ b/tinc-build/src/codegen/cel.rs @@ -16,7 +16,8 @@ pub(crate) fn eval_message_fmt( msg: &str, ctx: &compiler::Compiler<'_>, ) -> anyhow::Result { - let fmt = runtime_format::ParsedFmt::new(msg).map_err(|err| anyhow::anyhow!("failed to parse message format: {err}"))?; + let fmt = runtime_format::ParsedFmt::new(msg) + .map_err(|err| anyhow::anyhow!("failed to parse message format: {err}"))?; let mut runtime_args = Vec::new(); let mut compile_time_args = HashMap::new(); @@ -24,7 +25,11 @@ pub(crate) fn eval_message_fmt( // each key itself a cel expression for key in fmt.keys() { let expr = cel_parser::parse(key).context("failed to parse cel expression")?; - match functions::String.compile(CompilerCtx::new(ctx.child(), Some(ctx.resolve(&expr)?), &[]))? { + match functions::String.compile(CompilerCtx::new( + ctx.child(), + Some(ctx.resolve(&expr)?), + &[], + ))? { CompiledExpr::Constant(ConstantCompiledExpr { value }) => { // we need to escape the '{' & '}' compile_time_args.insert(key, value); diff --git a/tinc-build/src/codegen/cel/compiler.rs b/tinc-build/src/codegen/cel/compiler.rs index 73c6b04..b5b5b4f 100644 --- a/tinc-build/src/codegen/cel/compiler.rs +++ b/tinc-build/src/codegen/cel/compiler.rs @@ -21,7 +21,9 @@ pub(crate) enum CompiledExpr { impl CompiledExpr { pub(crate) fn constant(value: impl CelValueConv<'static>) -> Self { - Self::Constant(ConstantCompiledExpr { value: value.conv() }) + Self::Constant(ConstantCompiledExpr { + value: value.conv(), + }) } pub(crate) fn runtime(ty: CelType, expr: syn::Expr) -> Self { @@ -243,8 +245,16 @@ pub(crate) struct CompilerCtx<'a> { } impl<'a> CompilerCtx<'a> { - pub(crate) fn new(compiler: Compiler<'a>, this: Option, args: &'a [cel_parser::Expression]) -> Self { - Self { this, args, compiler } + pub(crate) fn new( + compiler: Compiler<'a>, + this: Option, + args: &'a [cel_parser::Expression], + ) -> Self { + Self { + this, + args, + compiler, + } } } @@ -272,7 +282,10 @@ impl<'a> Compiler<'a> { self.functions.insert(name, DebugFunc(Arc::new(f))); } - pub(crate) fn resolve(&self, expr: &cel_parser::Expression) -> Result { + pub(crate) fn resolve( + &self, + expr: &cel_parser::Expression, + ) -> Result { resolve::resolve(self, expr) } @@ -286,7 +299,10 @@ impl<'a> Compiler<'a> { } } - pub(crate) fn get_function(&self, name: &str) -> Option<&Arc> { + pub(crate) fn get_function( + &self, + name: &str, + ) -> Option<&Arc> { match self.functions.get(name) { Some(func) => Some(&func.0), None => match self.parent { @@ -311,15 +327,9 @@ pub(crate) enum CompileError { syntax: &'static str, }, #[error("type conversion error on type {ty:?}: {message}")] - TypeConversion { - ty: Box, - message: String, - }, + TypeConversion { ty: Box, message: String }, #[error("member access error on type {ty:?}: {message}")] - MemberAccess { - ty: Box, - message: String, - }, + MemberAccess { ty: Box, message: String }, #[error("variable not found: {0}")] VariableNotFound(String), #[error("function not found: {0}")] diff --git a/tinc-build/src/codegen/cel/compiler/helpers.rs b/tinc-build/src/codegen/cel/compiler/helpers.rs index b62da85..066a1d4 100644 --- a/tinc-build/src/codegen/cel/compiler/helpers.rs +++ b/tinc-build/src/codegen/cel/compiler/helpers.rs @@ -41,12 +41,14 @@ impl CompiledExpr { }) => CompiledExpr::Constant(ConstantCompiledExpr { value: tinc_cel::CelValue::Bool(true), }), - CompiledExpr::Runtime(RuntimeCompiledExpr { expr, .. }) => CompiledExpr::Runtime(RuntimeCompiledExpr { - expr: parse_quote! { - ::tinc::__private::cel::to_bool(#expr) - }, - ty: CelType::Proto(ProtoType::Value(ProtoValueType::Bool)), - }), + CompiledExpr::Runtime(RuntimeCompiledExpr { expr, .. }) => { + CompiledExpr::Runtime(RuntimeCompiledExpr { + expr: parse_quote! { + ::tinc::__private::cel::to_bool(#expr) + }, + ty: CelType::Proto(ProtoType::Value(ProtoValueType::Bool)), + }) + } CompiledExpr::Constant(ConstantCompiledExpr { value: CelValue::Enum(cel_enum), }) => CompiledExpr::Constant(ConstantCompiledExpr { @@ -57,9 +59,11 @@ impl CompiledExpr { .is_some_and(|e| e.variants.values().any(|v| v.value == cel_enum.value)), ), }), - CompiledExpr::Constant(ConstantCompiledExpr { value }) => CompiledExpr::Constant(ConstantCompiledExpr { - value: tinc_cel::CelValue::Bool(value.to_bool()), - }), + CompiledExpr::Constant(ConstantCompiledExpr { value }) => { + CompiledExpr::Constant(ConstantCompiledExpr { + value: tinc_cel::CelValue::Bool(value.to_bool()), + }) + } } } @@ -99,7 +103,8 @@ impl CompiledExpr { })), CompiledExpr::Runtime(RuntimeCompiledExpr { expr, - ty: CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Map(key_ty, value_ty))), + ty: + CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Map(key_ty, value_ty))), }) => { let key_to_cel = CompiledExpr::Runtime(RuntimeCompiledExpr { expr: parse_quote!(key), @@ -197,7 +202,10 @@ impl CompiledExpr { }), // Currently any is not supported. CompiledExpr::Runtime(RuntimeCompiledExpr { - ty: ty @ CelType::Proto(ProtoType::Value(ProtoValueType::WellKnown(ProtoWellKnownType::Any))), + ty: + ty @ CelType::Proto(ProtoType::Value(ProtoValueType::WellKnown( + ProtoWellKnownType::Any, + ))), .. }) => Err(CompileError::TypeConversion { ty: Box::new(ty), diff --git a/tinc-build/src/codegen/cel/compiler/resolve.rs b/tinc-build/src/codegen/cel/compiler/resolve.rs index 7a86389..c1fac14 100644 --- a/tinc-build/src/codegen/cel/compiler/resolve.rs +++ b/tinc-build/src/codegen/cel/compiler/resolve.rs @@ -3,7 +3,9 @@ use quote::quote; use syn::parse_quote; use tinc_cel::CelValue; -use super::{CompileError, CompiledExpr, Compiler, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr}; +use super::{ + CompileError, CompiledExpr, Compiler, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr, +}; use crate::codegen::cel::types::CelType; use crate::types::{ProtoModifiedValueType, ProtoType, ProtoValueType}; @@ -12,7 +14,9 @@ pub(crate) fn resolve(ctx: &Compiler, expr: &Expression) -> Result resolve_and(ctx, left, right), Expression::Arithmetic(left, op, right) => resolve_arithmetic(ctx, left, op, right), Expression::Atom(atom) => resolve_atom(ctx, atom), - Expression::FunctionCall(func, this, args) => resolve_function_call(ctx, func, this.as_deref(), args), + Expression::FunctionCall(func, this, args) => { + resolve_function_call(ctx, func, this.as_deref(), args) + } Expression::Ident(ident) => resolve_ident(ctx, ident), Expression::List(items) => resolve_list(ctx, items), Expression::Map(items) => resolve_map(ctx, items), @@ -24,7 +28,11 @@ pub(crate) fn resolve(ctx: &Compiler, expr: &Expression) -> Result Result { +fn resolve_and( + ctx: &Compiler, + left: &Expression, + right: &Expression, +) -> Result { let left = ctx.resolve(left)?.into_bool(ctx); let right = ctx.resolve(right)?.into_bool(ctx); match (left, right) { @@ -95,8 +103,12 @@ fn resolve_atom(_: &Compiler, atom: &Atom) -> Result Atom::Int(v) => Ok(CompiledExpr::constant(v)), Atom::UInt(v) => Ok(CompiledExpr::constant(v)), Atom::Float(v) => Ok(CompiledExpr::constant(v)), - Atom::String(v) => Ok(CompiledExpr::constant(tinc_cel::CelValue::String(v.to_string().into()))), - Atom::Bytes(v) => Ok(CompiledExpr::constant(tinc_cel::CelValue::Bytes(v.to_vec().into()))), + Atom::String(v) => Ok(CompiledExpr::constant(tinc_cel::CelValue::String( + v.to_string().into(), + ))), + Atom::Bytes(v) => Ok(CompiledExpr::constant(tinc_cel::CelValue::Bytes( + v.to_vec().into(), + ))), Atom::Bool(v) => Ok(CompiledExpr::constant(v)), Atom::Null => Ok(CompiledExpr::constant(tinc_cel::CelValue::Null)), } @@ -109,7 +121,9 @@ fn resolve_function_call( args: &[Expression], ) -> Result { let Expression::Ident(func_name) = func else { - return Err(CompileError::UnsupportedFunctionCallIdentifierType(func.clone())); + return Err(CompileError::UnsupportedFunctionCallIdentifierType( + func.clone(), + )); }; let Some(func) = ctx.get_function(func_name) else { @@ -159,7 +173,10 @@ fn resolve_list(ctx: &Compiler, items: &[Expression]) -> Result Result { +fn resolve_map( + ctx: &Compiler, + items: &[(Expression, Expression)], +) -> Result { let items = items .iter() .map(|(key, value)| { @@ -169,10 +186,9 @@ fn resolve_map(ctx: &Compiler, items: &[(Expression, Expression)]) -> Result, CompileError>>()?; - if items - .iter() - .any(|(key, value)| matches!(key, CompiledExpr::Runtime(_)) || matches!(value, CompiledExpr::Runtime(_))) - { + if items.iter().any(|(key, value)| { + matches!(key, CompiledExpr::Runtime(_)) || matches!(value, CompiledExpr::Runtime(_)) + }) { let items = items.into_iter().map(|(key, value)| quote!((#key, #value))); Ok(CompiledExpr::runtime( CelType::CelValue, @@ -198,7 +214,11 @@ fn resolve_map(ctx: &Compiler, items: &[(Expression, Expression)]) -> Result Result { +fn resolve_member( + ctx: &Compiler, + expr: &Expression, + member: &Member, +) -> Result { let expr = ctx.resolve(expr)?; match member { Member::Attribute(attr) => { @@ -219,19 +239,25 @@ fn resolve_member(ctx: &Compiler, expr: &Expression, member: &Member) -> Result< CompiledExpr::Runtime(RuntimeCompiledExpr { expr, ty: - ty @ CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Optional(ProtoValueType::Message( - full_name, - )))), + ty @ CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Optional( + ProtoValueType::Message(full_name), + ))), }) => { let msg = ctx .registry() .get_message(full_name) .ok_or_else(|| CompileError::MissingMessage(full_name.clone()))?; - let field_ty = msg.fields.get(attr).ok_or_else(|| CompileError::MemberAccess { - ty: Box::new(ty.clone()), - message: format!("message {} does not have field {}", msg.full_name, attr), - })?; + let field_ty = + msg.fields + .get(attr) + .ok_or_else(|| CompileError::MemberAccess { + ty: Box::new(ty.clone()), + message: format!( + "message {} does not have field {}", + msg.full_name, attr + ), + })?; let field_ident = field_ty.rust_ident(); @@ -250,12 +276,20 @@ fn resolve_member(ctx: &Compiler, expr: &Expression, member: &Member) -> Result< } CompiledExpr::Runtime(RuntimeCompiledExpr { expr, - ty: ty @ CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::OneOf(oneof))), + ty: + ty @ CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::OneOf(oneof))), }) => { - let field_ty = oneof.fields.get(attr).ok_or_else(|| CompileError::MemberAccess { - ty: Box::new(ty.clone()), - message: format!("oneof {} does not have field {}", oneof.full_name, attr), - })?; + let field_ty = + oneof + .fields + .get(attr) + .ok_or_else(|| CompileError::MemberAccess { + ty: Box::new(ty.clone()), + message: format!( + "oneof {} does not have field {}", + oneof.full_name, attr + ), + })?; let field_ident = field_ty.rust_ident(); @@ -280,10 +314,16 @@ fn resolve_member(ctx: &Compiler, expr: &Expression, member: &Member) -> Result< .registry() .get_message(full_name) .ok_or_else(|| CompileError::MissingMessage(full_name.clone()))?; - let field_ty = msg.fields.get(attr).ok_or_else(|| CompileError::MemberAccess { - ty: Box::new(ty.clone()), - message: format!("message {} does not have field {}", msg.full_name, attr), - })?; + let field_ty = + msg.fields + .get(attr) + .ok_or_else(|| CompileError::MemberAccess { + ty: Box::new(ty.clone()), + message: format!( + "message {} does not have field {}", + msg.full_name, attr + ), + })?; let field_ident = field_ty.rust_ident(); @@ -296,7 +336,11 @@ fn resolve_member(ctx: &Compiler, expr: &Expression, member: &Member) -> Result< } CompiledExpr::Runtime(RuntimeCompiledExpr { expr, - ty: CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Map(ProtoValueType::String, value_ty))), + ty: + CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Map( + ProtoValueType::String, + value_ty, + ))), }) => Ok(CompiledExpr::runtime( CelType::Proto(ProtoType::Value(value_ty.clone())), parse_quote! { @@ -306,13 +350,16 @@ fn resolve_member(ctx: &Compiler, expr: &Expression, member: &Member) -> Result< )? }, )), - CompiledExpr::Runtime(RuntimeCompiledExpr { ty, .. }) => Err(CompileError::MemberAccess { - ty: Box::new(ty.clone()), - message: "can only access attributes on messages and maps with string keys".to_string(), - }), - CompiledExpr::Constant(ConstantCompiledExpr { value: container }) => { - Ok(CompiledExpr::constant(tinc_cel::CelValue::cel_access(container, attr)?)) + CompiledExpr::Runtime(RuntimeCompiledExpr { ty, .. }) => { + Err(CompileError::MemberAccess { + ty: Box::new(ty.clone()), + message: "can only access attributes on messages and maps with string keys" + .to_string(), + }) } + CompiledExpr::Constant(ConstantCompiledExpr { value: container }) => Ok( + CompiledExpr::constant(tinc_cel::CelValue::cel_access(container, attr)?), + ), } } Member::Index(idx) => { @@ -320,20 +367,26 @@ fn resolve_member(ctx: &Compiler, expr: &Expression, member: &Member) -> Result< match (expr, idx) { ( expr @ CompiledExpr::Runtime(RuntimeCompiledExpr { - ty: CelType::CelValue, .. + ty: CelType::CelValue, + .. }), idx, ) - | (expr @ CompiledExpr::Constant(_), idx @ CompiledExpr::Runtime(_)) => Ok(CompiledExpr::runtime( - CelType::CelValue, - parse_quote! { - ::tinc::__private::cel::CelValue::cel_access(#expr, #idx)? - }, - )), + | (expr @ CompiledExpr::Constant(_), idx @ CompiledExpr::Runtime(_)) => { + Ok(CompiledExpr::runtime( + CelType::CelValue, + parse_quote! { + ::tinc::__private::cel::CelValue::cel_access(#expr, #idx)? + }, + )) + } ( CompiledExpr::Runtime(RuntimeCompiledExpr { expr, - ty: CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated(item_ty))), + ty: + CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated( + item_ty, + ))), }), idx, ) => Ok(CompiledExpr::runtime( @@ -348,7 +401,11 @@ fn resolve_member(ctx: &Compiler, expr: &Expression, member: &Member) -> Result< ( CompiledExpr::Runtime(RuntimeCompiledExpr { expr, - ty: CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Map(_, value_ty))), + ty: + CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Map( + _, + value_ty, + ))), }), idx, ) => Ok(CompiledExpr::runtime( @@ -360,21 +417,29 @@ fn resolve_member(ctx: &Compiler, expr: &Expression, member: &Member) -> Result< )? }, )), - (CompiledExpr::Runtime(RuntimeCompiledExpr { ty, .. }), _) => Err(CompileError::MemberAccess { - ty: Box::new(ty.clone()), - message: "cannot index into non-repeated and non-map values".to_string(), - }), + (CompiledExpr::Runtime(RuntimeCompiledExpr { ty, .. }), _) => { + Err(CompileError::MemberAccess { + ty: Box::new(ty.clone()), + message: "cannot index into non-repeated and non-map values".to_string(), + }) + } ( CompiledExpr::Constant(ConstantCompiledExpr { value: container }), CompiledExpr::Constant(ConstantCompiledExpr { value: idx }), - ) => Ok(CompiledExpr::constant(tinc_cel::CelValue::cel_access(container, idx)?)), + ) => Ok(CompiledExpr::constant(tinc_cel::CelValue::cel_access( + container, idx, + )?)), } } Member::Fields(_) => Err(CompileError::NotImplemented), } } -fn resolve_or(ctx: &Compiler, left: &Expression, right: &Expression) -> Result { +fn resolve_or( + ctx: &Compiler, + left: &Expression, + right: &Expression, +) -> Result { let left = ctx.resolve(left)?.into_bool(ctx); let right = ctx.resolve(right)?.into_bool(ctx); match (left, right) { @@ -423,7 +488,9 @@ fn resolve_relation( CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated(_))) => { quote! { array_contains } } - CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Map(_, _))) => quote! { map_contains }, + CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Map(_, _))) => { + quote! { map_contains } + } _ => unreachable!(), }; @@ -448,7 +515,9 @@ fn resolve_relation( RelationOp::LessThan => Ok(CompiledExpr::constant(CelValue::cel_lt(left, right)?)), RelationOp::LessThanEq => Ok(CompiledExpr::constant(CelValue::cel_lte(left, right)?)), RelationOp::GreaterThan => Ok(CompiledExpr::constant(CelValue::cel_gt(left, right)?)), - RelationOp::GreaterThanEq => Ok(CompiledExpr::constant(CelValue::cel_gte(left, right)?)), + RelationOp::GreaterThanEq => { + Ok(CompiledExpr::constant(CelValue::cel_gte(left, right)?)) + } RelationOp::Equals => Ok(CompiledExpr::constant(CelValue::cel_eq(left, right)?)), RelationOp::NotEquals => Ok(CompiledExpr::constant(CelValue::cel_neq(left, right)?)), RelationOp::In => Ok(CompiledExpr::constant(CelValue::cel_in(left, right)?)), @@ -508,13 +577,19 @@ fn resolve_ternary( } } -fn resolve_unary(ctx: &Compiler, op: &cel_parser::UnaryOp, expr: &Expression) -> Result { +fn resolve_unary( + ctx: &Compiler, + op: &cel_parser::UnaryOp, + expr: &Expression, +) -> Result { let expr = ctx.resolve(expr)?; match op { cel_parser::UnaryOp::Not => { let expr = expr.into_bool(ctx); match expr { - CompiledExpr::Constant(ConstantCompiledExpr { value: expr }) => Ok(CompiledExpr::constant(!expr.to_bool())), + CompiledExpr::Constant(ConstantCompiledExpr { value: expr }) => { + Ok(CompiledExpr::constant(!expr.to_bool())) + } expr => Ok(CompiledExpr::runtime( CelType::Proto(ProtoType::Value(ProtoValueType::Bool)), parse_quote! { @@ -555,7 +630,11 @@ mod tests { #[test] fn test_resolve_atom_int() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let expr = parse_cel("1").unwrap(); insta::assert_debug_snapshot!(resolve(&compiler, &expr), @r" @@ -575,7 +654,11 @@ mod tests { #[test] fn test_resolve_atom_uint() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let expr = parse_cel("3u").unwrap(); insta::assert_debug_snapshot!(resolve(&compiler, &expr), @r" @@ -595,7 +678,11 @@ mod tests { #[test] fn test_resolve_atom_float() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let expr = parse_cel("1.23").unwrap(); insta::assert_debug_snapshot!(resolve(&compiler, &expr), @r" @@ -615,7 +702,11 @@ mod tests { #[test] fn test_resolve_atom_string_bytes_bool_null() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let expr_str = parse_cel("\"foo\"").unwrap(); @@ -675,7 +766,11 @@ mod tests { #[test] fn test_resolve_arithmetic_constant() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let expr = parse_cel("10 + 5").unwrap(); @@ -756,7 +851,11 @@ mod tests { #[test] fn test_resolve_relation_constant() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let expr = parse_cel("1 < 2").unwrap(); @@ -847,7 +946,11 @@ mod tests { #[test] fn test_resolve_boolean_constant() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let expr_and = parse_cel("true && false").unwrap(); @@ -879,7 +982,11 @@ mod tests { #[test] fn test_resolve_unary_constant() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let expr_not = parse_cel("!false").unwrap(); @@ -941,7 +1048,11 @@ mod tests { #[test] fn test_resolve_ternary_constant() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let expr_true = parse_cel("true ? 1 : 2").unwrap(); @@ -977,7 +1088,11 @@ mod tests { #[test] fn test_resolve_list_map_constant() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let expr_list = parse_cel("[1, 2, 3]").unwrap(); @@ -1050,7 +1165,11 @@ mod tests { #[test] fn test_resolve_negative_variable() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let mut compiler = Compiler::new(®istry); compiler.add_variable("x", CompiledExpr::constant(CelValue::Number(1.into()))); @@ -1073,7 +1192,11 @@ mod tests { #[test] fn test_resolve_access() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let expr_list = parse_cel("[1, 2, 3][2]").unwrap(); diff --git a/tinc-build/src/codegen/cel/functions/all.rs b/tinc-build/src/codegen/cel/functions/all.rs index 5a74bde..8af4cd2 100644 --- a/tinc-build/src/codegen/cel/functions/all.rs +++ b/tinc-build/src/codegen/cel/functions/all.rs @@ -4,7 +4,9 @@ use syn::parse_quote; use tinc_cel::CelValue; use super::Function; -use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr}; +use crate::codegen::cel::compiler::{ + CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr, +}; use crate::codegen::cel::types::CelType; use crate::types::{ProtoModifiedValueType, ProtoType, ProtoValueType}; @@ -42,11 +44,17 @@ impl Function for All { }; if ctx.args.len() != 2 { - return Err(CompileError::syntax("invalid number of args, expected 2", self)); + return Err(CompileError::syntax( + "invalid number of args, expected 2", + self, + )); } let cel_parser::Expression::Ident(variable) = &ctx.args[0] else { - return Err(CompileError::syntax("first argument must be an ident", self)); + return Err(CompileError::syntax( + "first argument must be an ident", + self, + )); }; match this { @@ -55,14 +63,20 @@ impl Function for All { match ty { CelType::CelValue => { - child_ctx.add_variable(variable, CompiledExpr::runtime(CelType::CelValue, parse_quote!(item))); + child_ctx.add_variable( + variable, + CompiledExpr::runtime(CelType::CelValue, parse_quote!(item)), + ); } CelType::Proto(ProtoType::Modified( ProtoModifiedValueType::Repeated(ty) | ProtoModifiedValueType::Map(ty, _), )) => { child_ctx.add_variable( variable, - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ty.clone())), parse_quote!(item)), + CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ty.clone())), + parse_quote!(item), + ), ); } v => { @@ -88,9 +102,9 @@ impl Function for All { CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Map(_, _))) => { native_impl(quote!((#expr).keys()), parse_quote!(item), arg) } - CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated(_))) => { - native_impl(quote!((#expr).iter()), parse_quote!(item), arg) - } + CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated( + _, + ))) => native_impl(quote!((#expr).iter()), parse_quote!(item), arg), _ => unreachable!(), }, )) @@ -103,34 +117,48 @@ impl Function for All { child_ctx.add_variable(variable, CompiledExpr::constant(value)); - child_ctx.resolve(&ctx.args[1]).map(|v| v.into_bool(&child_ctx)) + child_ctx + .resolve(&ctx.args[1]) + .map(|v| v.into_bool(&child_ctx)) }; let collected: Result, _> = match value { CelValue::List(item) => item.iter().cloned().map(compile_val).collect(), - CelValue::Map(item) => item.iter().map(|(key, _)| key).cloned().map(compile_val).collect(), + CelValue::Map(item) => item + .iter() + .map(|(key, _)| key) + .cloned() + .map(compile_val) + .collect(), _ => unreachable!(), }; let collected = collected?; - if collected.iter().any(|c| matches!(c, CompiledExpr::Runtime(_))) { + if collected + .iter() + .any(|c| matches!(c, CompiledExpr::Runtime(_))) + { Ok(CompiledExpr::runtime( CelType::Proto(ProtoType::Value(ProtoValueType::Bool)), native_impl(quote!([#(#collected),*]), parse_quote!(item), quote!(item)), )) } else { - Ok(CompiledExpr::constant(CelValue::Bool(collected.into_iter().all( - |c| match c { - CompiledExpr::Constant(ConstantCompiledExpr { value }) => value.to_bool(), + Ok(CompiledExpr::constant(CelValue::Bool( + collected.into_iter().all(|c| match c { + CompiledExpr::Constant(ConstantCompiledExpr { value }) => { + value.to_bool() + } _ => unreachable!("all values must be constant"), - }, - )))) + }), + ))) } } - CompiledExpr::Constant(ConstantCompiledExpr { value }) => Err(CompileError::TypeConversion { - ty: Box::new(CelType::CelValue), - message: format!("{value:?} cannot be iterated over"), - }), + CompiledExpr::Constant(ConstantCompiledExpr { value }) => { + Err(CompileError::TypeConversion { + ty: Box::new(CelType::CelValue), + message: format!("{value:?} cannot be iterated over"), + }) + } } } } @@ -152,7 +180,11 @@ mod tests { #[test] fn test_all_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(All.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( @@ -281,7 +313,11 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_all_cel_value() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let map = CompiledExpr::runtime(CelType::CelValue, parse_quote!(input)); @@ -329,7 +365,11 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_all_proto_map() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let map = CompiledExpr::runtime( @@ -395,11 +435,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_all_proto_repeated() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let repeated = CompiledExpr::runtime( - CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated(ProtoValueType::Int32))), + CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated( + ProtoValueType::Int32, + ))), parse_quote!(input), ); @@ -446,10 +492,16 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_all_const_needs_runtime() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); - let list = CompiledExpr::constant(CelValue::List([CelValue::Number(0.into())].into_iter().collect())); + let list = CompiledExpr::constant(CelValue::List( + [CelValue::Number(0.into())].into_iter().collect(), + )); let result = All .compile(CompilerCtx::new( @@ -490,11 +542,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_all_runtime() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let list = CompiledExpr::runtime( - CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated(ProtoValueType::Int32))), + CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated( + ProtoValueType::Int32, + ))), parse_quote!(input), ); diff --git a/tinc-build/src/codegen/cel/functions/bool.rs b/tinc-build/src/codegen/cel/functions/bool.rs index f33e8d6..5c099db 100644 --- a/tinc-build/src/codegen/cel/functions/bool.rs +++ b/tinc-build/src/codegen/cel/functions/bool.rs @@ -40,7 +40,11 @@ mod tests { #[test] fn test_bool_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(Bool.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( diff --git a/tinc-build/src/codegen/cel/functions/bytes.rs b/tinc-build/src/codegen/cel/functions/bytes.rs index add392e..3c8b85f 100644 --- a/tinc-build/src/codegen/cel/functions/bytes.rs +++ b/tinc-build/src/codegen/cel/functions/bytes.rs @@ -2,7 +2,9 @@ use syn::parse_quote; use tinc_cel::CelValue; use super::Function; -use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr}; +use crate::codegen::cel::compiler::{ + CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr, +}; use crate::codegen::cel::types::CelType; #[derive(Debug, Clone, Default)] @@ -55,7 +57,11 @@ mod tests { #[test] fn test_bytes_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(Bytes.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( @@ -98,11 +104,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_bytes_runtime() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); - let string_value = - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ProtoValueType::String)), parse_quote!(input)); + let string_value = CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ProtoValueType::String)), + parse_quote!(input), + ); let output = Bytes .compile(CompilerCtx::new(compiler.child(), Some(string_value), &[])) diff --git a/tinc-build/src/codegen/cel/functions/contains.rs b/tinc-build/src/codegen/cel/functions/contains.rs index 590c278..ddf9d02 100644 --- a/tinc-build/src/codegen/cel/functions/contains.rs +++ b/tinc-build/src/codegen/cel/functions/contains.rs @@ -3,7 +3,9 @@ use syn::parse_quote; use tinc_cel::CelValue; use super::Function; -use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr}; +use crate::codegen::cel::compiler::{ + CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr, +}; use crate::codegen::cel::types::CelType; use crate::types::{ProtoModifiedValueType, ProtoType, ProtoValueType}; @@ -39,7 +41,10 @@ impl Function for Contains { ProtoModifiedValueType::Repeated(item) | ProtoModifiedValueType::Map(item, _), )), }) = &this - && !matches!(item, ProtoValueType::Message { .. } | ProtoValueType::Enum(_)) + && !matches!( + item, + ProtoValueType::Message { .. } | ProtoValueType::Enum(_) + ) { let op = match &ty { CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated(_))) => { @@ -99,7 +104,11 @@ mod tests { #[test] fn test_contains_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(Contains.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( @@ -137,11 +146,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_contains_runtime_string() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); - let string_value = - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ProtoValueType::String)), parse_quote!(input)); + let string_value = CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ProtoValueType::String)), + parse_quote!(input), + ); let output = Contains .compile(CompilerCtx::new( @@ -175,7 +190,11 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_contains_runtime_map() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let string_value = CompiledExpr::runtime( @@ -232,11 +251,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_contains_runtime_repeated() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let string_value = CompiledExpr::runtime( - CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated(ProtoValueType::String))), + CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated( + ProtoValueType::String, + ))), parse_quote!(input), ); diff --git a/tinc-build/src/codegen/cel/functions/double.rs b/tinc-build/src/codegen/cel/functions/double.rs index b017f7c..e402f0b 100644 --- a/tinc-build/src/codegen/cel/functions/double.rs +++ b/tinc-build/src/codegen/cel/functions/double.rs @@ -2,7 +2,9 @@ use syn::parse_quote; use tinc_cel::CelValue; use super::Function; -use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr}; +use crate::codegen::cel::compiler::{ + CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr, +}; use crate::codegen::cel::types::CelType; #[derive(Debug, Clone, Default)] @@ -54,7 +56,11 @@ mod tests { #[test] fn test_double_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(Double.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( @@ -94,11 +100,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_double_runtime() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); - let string_value = - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ProtoValueType::String)), parse_quote!(input)); + let string_value = CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ProtoValueType::String)), + parse_quote!(input), + ); let output = Double .compile(CompilerCtx::new(compiler.child(), Some(string_value), &[])) diff --git a/tinc-build/src/codegen/cel/functions/ends_with.rs b/tinc-build/src/codegen/cel/functions/ends_with.rs index 596839a..11df9a6 100644 --- a/tinc-build/src/codegen/cel/functions/ends_with.rs +++ b/tinc-build/src/codegen/cel/functions/ends_with.rs @@ -2,7 +2,9 @@ use syn::parse_quote; use tinc_cel::CelValue; use super::Function; -use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr}; +use crate::codegen::cel::compiler::{ + CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, +}; use crate::codegen::cel::types::CelType; use crate::types::{ProtoType, ProtoValueType}; @@ -65,7 +67,11 @@ mod tests { #[test] fn test_ends_with_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(EndsWith.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( @@ -103,11 +109,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_ends_with_runtime() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); - let string_value = - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ProtoValueType::String)), parse_quote!(input)); + let string_value = CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ProtoValueType::String)), + parse_quote!(input), + ); let output = EndsWith .compile(CompilerCtx::new( diff --git a/tinc-build/src/codegen/cel/functions/enum_.rs b/tinc-build/src/codegen/cel/functions/enum_.rs index c788a0b..af254e1 100644 --- a/tinc-build/src/codegen/cel/functions/enum_.rs +++ b/tinc-build/src/codegen/cel/functions/enum_.rs @@ -2,7 +2,9 @@ use syn::parse_quote; use tinc_cel::CelValue; use super::Function; -use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr}; +use crate::codegen::cel::compiler::{ + CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr, +}; use crate::codegen::cel::types::CelType; use crate::types::{ProtoModifiedValueType, ProtoPath, ProtoType, ProtoValueType}; @@ -34,7 +36,9 @@ impl Function for Enum { ( CompiledExpr::Runtime(RuntimeCompiledExpr { ty: - CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Optional(ProtoValueType::Enum(path)))) + CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Optional( + ProtoValueType::Enum(path), + ))) | CelType::Proto(ProtoType::Value(ProtoValueType::Enum(path))), .. }), @@ -59,7 +63,9 @@ impl Function for Enum { ( CompiledExpr::Constant(ConstantCompiledExpr { value: this }), CompiledExpr::Constant(ConstantCompiledExpr { value: enum_path }), - ) => Ok(CompiledExpr::constant(CelValue::cel_to_enum(this, enum_path)?)), + ) => Ok(CompiledExpr::constant(CelValue::cel_to_enum( + this, enum_path, + )?)), (this, enum_path) => Ok(CompiledExpr::runtime( CelType::CelValue, parse_quote! { @@ -88,7 +94,11 @@ mod tests { #[test] fn test_enum_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let enum_ = Enum(None); insta::assert_debug_snapshot!(enum_.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" @@ -132,11 +142,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_enum_runtime() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); - let string_value = - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ProtoValueType::Int32)), parse_quote!(input)); + let string_value = CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ProtoValueType::Int32)), + parse_quote!(input), + ); let output = Enum(None) .compile(CompilerCtx::new( diff --git a/tinc-build/src/codegen/cel/functions/exists.rs b/tinc-build/src/codegen/cel/functions/exists.rs index 4f8b69d..1d73ee7 100644 --- a/tinc-build/src/codegen/cel/functions/exists.rs +++ b/tinc-build/src/codegen/cel/functions/exists.rs @@ -4,7 +4,9 @@ use syn::parse_quote; use tinc_cel::CelValue; use super::Function; -use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr}; +use crate::codegen::cel::compiler::{ + CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr, +}; use crate::codegen::cel::types::CelType; use crate::types::{ProtoModifiedValueType, ProtoType, ProtoValueType}; @@ -46,7 +48,10 @@ impl Function for Exists { } let cel_parser::Expression::Ident(variable) = &ctx.args[0] else { - return Err(CompileError::syntax("first argument must be an ident", self)); + return Err(CompileError::syntax( + "first argument must be an ident", + self, + )); }; match this { @@ -55,14 +60,20 @@ impl Function for Exists { match &ty { CelType::CelValue => { - child_ctx.add_variable(variable, CompiledExpr::runtime(CelType::CelValue, parse_quote!(item))); + child_ctx.add_variable( + variable, + CompiledExpr::runtime(CelType::CelValue, parse_quote!(item)), + ); } CelType::Proto(ProtoType::Modified( ProtoModifiedValueType::Repeated(ty) | ProtoModifiedValueType::Map(ty, _), )) => { child_ctx.add_variable( variable, - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ty.clone())), parse_quote!(item)), + CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ty.clone())), + parse_quote!(item), + ), ); } v => { @@ -88,9 +99,9 @@ impl Function for Exists { CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Map(_, _))) => { native_impl(quote!((#expr).keys()), parse_quote!(item), arg) } - CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated(_))) => { - native_impl(quote!((#expr).iter()), parse_quote!(item), arg) - } + CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated( + _, + ))) => native_impl(quote!((#expr).iter()), parse_quote!(item), arg), _ => unreachable!(), }, )) @@ -103,34 +114,48 @@ impl Function for Exists { child_ctx.add_variable(variable, CompiledExpr::constant(value)); - child_ctx.resolve(&ctx.args[1]).map(|v| v.into_bool(&child_ctx)) + child_ctx + .resolve(&ctx.args[1]) + .map(|v| v.into_bool(&child_ctx)) }; let collected: Result, _> = match value { CelValue::List(item) => item.iter().cloned().map(compile_val).collect(), - CelValue::Map(item) => item.iter().map(|(key, _)| key).cloned().map(compile_val).collect(), + CelValue::Map(item) => item + .iter() + .map(|(key, _)| key) + .cloned() + .map(compile_val) + .collect(), _ => unreachable!(), }; let collected = collected?; - if collected.iter().any(|c| matches!(c, CompiledExpr::Runtime(_))) { + if collected + .iter() + .any(|c| matches!(c, CompiledExpr::Runtime(_))) + { Ok(CompiledExpr::runtime( CelType::Proto(ProtoType::Value(ProtoValueType::Bool)), native_impl(quote!([#(#collected),*]), parse_quote!(item), quote!(item)), )) } else { - Ok(CompiledExpr::constant(CelValue::Bool(collected.into_iter().any( - |c| match c { - CompiledExpr::Constant(ConstantCompiledExpr { value }) => value.to_bool(), + Ok(CompiledExpr::constant(CelValue::Bool( + collected.into_iter().any(|c| match c { + CompiledExpr::Constant(ConstantCompiledExpr { value }) => { + value.to_bool() + } _ => unreachable!("all values must be constant"), - }, - )))) + }), + ))) } } - CompiledExpr::Constant(ConstantCompiledExpr { value }) => Err(CompileError::TypeConversion { - ty: Box::new(CelType::CelValue), - message: format!("{value:?} cannot be iterated over"), - }), + CompiledExpr::Constant(ConstantCompiledExpr { value }) => { + Err(CompileError::TypeConversion { + ty: Box::new(CelType::CelValue), + message: format!("{value:?} cannot be iterated over"), + }) + } } } } @@ -152,7 +177,11 @@ mod tests { #[test] fn test_exists_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(Exists.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( @@ -219,7 +248,11 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_exists_runtime_map() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let string_value = CompiledExpr::runtime( @@ -234,7 +267,10 @@ mod tests { .compile(CompilerCtx::new( compiler.child(), Some(string_value), - &[cel_parser::parse("x").unwrap(), cel_parser::parse("x == 'value'").unwrap()], + &[ + cel_parser::parse("x").unwrap(), + cel_parser::parse("x == 'value'").unwrap(), + ], )) .unwrap(); @@ -276,11 +312,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_exists_runtime_repeated() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let string_value = CompiledExpr::runtime( - CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated(ProtoValueType::String))), + CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated( + ProtoValueType::String, + ))), parse_quote!(input), ); @@ -288,7 +330,10 @@ mod tests { .compile(CompilerCtx::new( compiler.child(), Some(string_value), - &[cel_parser::parse("x").unwrap(), cel_parser::parse("x == 'value'").unwrap()], + &[ + cel_parser::parse("x").unwrap(), + cel_parser::parse("x == 'value'").unwrap(), + ], )) .unwrap(); @@ -318,7 +363,11 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_exists_runtime_cel_value() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let string_value = CompiledExpr::runtime(CelType::CelValue, parse_quote!(input)); @@ -327,7 +376,10 @@ mod tests { .compile(CompilerCtx::new( compiler.child(), Some(string_value), - &[cel_parser::parse("x").unwrap(), cel_parser::parse("x == 'value'").unwrap()], + &[ + cel_parser::parse("x").unwrap(), + cel_parser::parse("x == 'value'").unwrap(), + ], )) .unwrap(); @@ -368,20 +420,31 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_exists_const_requires_runtime() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let list_value = CompiledExpr::constant(CelValue::List( - [CelValueConv::conv(5), CelValueConv::conv(0), CelValueConv::conv(1)] - .into_iter() - .collect(), + [ + CelValueConv::conv(5), + CelValueConv::conv(0), + CelValueConv::conv(1), + ] + .into_iter() + .collect(), )); let output = Exists .compile(CompilerCtx::new( compiler.child(), Some(list_value), - &[cel_parser::parse("x").unwrap(), cel_parser::parse("dyn(x >= 1)").unwrap()], + &[ + cel_parser::parse("x").unwrap(), + cel_parser::parse("dyn(x >= 1)").unwrap(), + ], )) .unwrap(); diff --git a/tinc-build/src/codegen/cel/functions/exists_one.rs b/tinc-build/src/codegen/cel/functions/exists_one.rs index 6564452..a981f43 100644 --- a/tinc-build/src/codegen/cel/functions/exists_one.rs +++ b/tinc-build/src/codegen/cel/functions/exists_one.rs @@ -4,7 +4,9 @@ use syn::parse_quote; use tinc_cel::CelValue; use super::Function; -use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr}; +use crate::codegen::cel::compiler::{ + CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr, +}; use crate::codegen::cel::types::CelType; use crate::types::{ProtoModifiedValueType, ProtoType, ProtoValueType}; @@ -51,7 +53,10 @@ impl Function for ExistsOne { } let cel_parser::Expression::Ident(variable) = &ctx.args[0] else { - return Err(CompileError::syntax("first argument must be an ident", self)); + return Err(CompileError::syntax( + "first argument must be an ident", + self, + )); }; match this { @@ -60,14 +65,20 @@ impl Function for ExistsOne { match &ty { CelType::CelValue => { - child_ctx.add_variable(variable, CompiledExpr::runtime(CelType::CelValue, parse_quote!(item))); + child_ctx.add_variable( + variable, + CompiledExpr::runtime(CelType::CelValue, parse_quote!(item)), + ); } CelType::Proto(ProtoType::Modified( ProtoModifiedValueType::Repeated(ty) | ProtoModifiedValueType::Map(ty, _), )) => { child_ctx.add_variable( variable, - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ty.clone())), parse_quote!(item)), + CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ty.clone())), + parse_quote!(item), + ), ); } v => { @@ -93,9 +104,9 @@ impl Function for ExistsOne { CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Map(_, _))) => { native_impl(quote!((#expr).keys()), parse_quote!(item), arg) } - CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated(_))) => { - native_impl(quote!((#expr).iter()), parse_quote!(item), arg) - } + CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated( + _, + ))) => native_impl(quote!((#expr).iter()), parse_quote!(item), arg), _ => unreachable!(), }, )) @@ -108,17 +119,27 @@ impl Function for ExistsOne { child_ctx.add_variable(variable, CompiledExpr::constant(value)); - child_ctx.resolve(&ctx.args[1]).map(|v| v.into_bool(&child_ctx)) + child_ctx + .resolve(&ctx.args[1]) + .map(|v| v.into_bool(&child_ctx)) }; let collected: Result, _> = match value { CelValue::List(item) => item.iter().cloned().map(compile_val).collect(), - CelValue::Map(item) => item.iter().map(|(key, _)| key).cloned().map(compile_val).collect(), + CelValue::Map(item) => item + .iter() + .map(|(key, _)| key) + .cloned() + .map(compile_val) + .collect(), _ => unreachable!(), }; let collected = collected?; - if collected.iter().any(|c| matches!(c, CompiledExpr::Runtime(_))) { + if collected + .iter() + .any(|c| matches!(c, CompiledExpr::Runtime(_))) + { Ok(CompiledExpr::runtime( CelType::Proto(ProtoType::Value(ProtoValueType::Bool)), native_impl(quote!([#(#collected),*]), parse_quote!(item), quote!(item)), @@ -128,7 +149,9 @@ impl Function for ExistsOne { collected .into_iter() .filter(|c| match c { - CompiledExpr::Constant(ConstantCompiledExpr { value }) => value.to_bool(), + CompiledExpr::Constant(ConstantCompiledExpr { value }) => { + value.to_bool() + } _ => unreachable!("all values must be constant"), }) .count() @@ -136,10 +159,12 @@ impl Function for ExistsOne { ))) } } - CompiledExpr::Constant(ConstantCompiledExpr { value }) => Err(CompileError::TypeConversion { - ty: Box::new(CelType::CelValue), - message: format!("{value:?} cannot be iterated over"), - }), + CompiledExpr::Constant(ConstantCompiledExpr { value }) => { + Err(CompileError::TypeConversion { + ty: Box::new(CelType::CelValue), + message: format!("{value:?} cannot be iterated over"), + }) + } } } } @@ -161,7 +186,11 @@ mod tests { #[test] fn test_exists_one_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(ExistsOne.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( @@ -227,7 +256,9 @@ mod tests { "); let input = CompiledExpr::constant(CelValue::Map( - [(CelValueConv::conv("value"), CelValueConv::conv(1))].into_iter().collect(), + [(CelValueConv::conv("value"), CelValueConv::conv(1))] + .into_iter() + .collect(), )); let mut ctx = compiler.child(); ctx.add_variable("input", input.clone()); @@ -251,7 +282,11 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_exists_one_runtime_map() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let string_value = CompiledExpr::runtime( @@ -266,7 +301,10 @@ mod tests { .compile(CompilerCtx::new( compiler.child(), Some(string_value), - &[cel_parser::parse("x").unwrap(), cel_parser::parse("x == 'value'").unwrap()], + &[ + cel_parser::parse("x").unwrap(), + cel_parser::parse("x == 'value'").unwrap(), + ], )) .unwrap(); @@ -308,11 +346,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_exists_one_runtime_repeated() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let string_value = CompiledExpr::runtime( - CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated(ProtoValueType::String))), + CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated( + ProtoValueType::String, + ))), parse_quote!(input), ); @@ -320,7 +364,10 @@ mod tests { .compile(CompilerCtx::new( compiler.child(), Some(string_value), - &[cel_parser::parse("x").unwrap(), cel_parser::parse("x == 'value'").unwrap()], + &[ + cel_parser::parse("x").unwrap(), + cel_parser::parse("x == 'value'").unwrap(), + ], )) .unwrap(); @@ -350,7 +397,11 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_exists_one_runtime_cel_value() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let string_value = CompiledExpr::runtime(CelType::CelValue, parse_quote!(input)); @@ -359,7 +410,10 @@ mod tests { .compile(CompilerCtx::new( compiler.child(), Some(string_value), - &[cel_parser::parse("x").unwrap(), cel_parser::parse("x == 'value'").unwrap()], + &[ + cel_parser::parse("x").unwrap(), + cel_parser::parse("x == 'value'").unwrap(), + ], )) .unwrap(); @@ -400,20 +454,31 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_exists_one_const_requires_runtime() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let list_value = CompiledExpr::constant(CelValue::List( - [CelValueConv::conv(5), CelValueConv::conv(0), CelValueConv::conv(1)] - .into_iter() - .collect(), + [ + CelValueConv::conv(5), + CelValueConv::conv(0), + CelValueConv::conv(1), + ] + .into_iter() + .collect(), )); let output = ExistsOne .compile(CompilerCtx::new( compiler.child(), Some(list_value), - &[cel_parser::parse("x").unwrap(), cel_parser::parse("dyn(x >= 1)").unwrap()], + &[ + cel_parser::parse("x").unwrap(), + cel_parser::parse("dyn(x >= 1)").unwrap(), + ], )) .unwrap(); diff --git a/tinc-build/src/codegen/cel/functions/filter.rs b/tinc-build/src/codegen/cel/functions/filter.rs index 32efdb1..5ac7b2d 100644 --- a/tinc-build/src/codegen/cel/functions/filter.rs +++ b/tinc-build/src/codegen/cel/functions/filter.rs @@ -4,7 +4,9 @@ use syn::parse_quote; use tinc_cel::CelValue; use super::Function; -use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr}; +use crate::codegen::cel::compiler::{ + CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr, +}; use crate::codegen::cel::types::CelType; use crate::types::{ProtoModifiedValueType, ProtoType, ProtoValueType}; @@ -50,7 +52,10 @@ impl Function for Filter { } let cel_parser::Expression::Ident(variable) = &ctx.args[0] else { - return Err(CompileError::syntax("first argument must be an ident", self)); + return Err(CompileError::syntax( + "first argument must be an ident", + self, + )); }; match this { @@ -59,14 +64,20 @@ impl Function for Filter { match ty { CelType::CelValue => { - child_ctx.add_variable(variable, CompiledExpr::runtime(CelType::CelValue, parse_quote!(item))); + child_ctx.add_variable( + variable, + CompiledExpr::runtime(CelType::CelValue, parse_quote!(item)), + ); } CelType::Proto(ProtoType::Modified( ProtoModifiedValueType::Repeated(ty) | ProtoModifiedValueType::Map(ty, _), )) => { child_ctx.add_variable( variable, - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ty.clone())), parse_quote!(item)), + CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ty.clone())), + parse_quote!(item), + ), ); } v => { @@ -90,9 +101,11 @@ impl Function for Filter { })? }, CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Map(ty, _))) => { - let cel_ty = - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ty.clone())), parse_quote!(item)) - .into_cel()?; + let cel_ty = CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ty.clone())), + parse_quote!(item), + ) + .into_cel()?; native_impl( quote!( @@ -102,10 +115,14 @@ impl Function for Filter { arg, ) } - CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated(ty))) => { - let cel_ty = - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ty.clone())), parse_quote!(item)) - .into_cel()?; + CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated( + ty, + ))) => { + let cel_ty = CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ty.clone())), + parse_quote!(item), + ) + .into_cel()?; native_impl( quote!( @@ -127,17 +144,27 @@ impl Function for Filter { child_ctx.add_variable(variable, CompiledExpr::constant(value.clone())); - child_ctx.resolve(&ctx.args[1]).map(|v| (value, v.into_bool(&child_ctx))) + child_ctx + .resolve(&ctx.args[1]) + .map(|v| (value, v.into_bool(&child_ctx))) }; let collected: Result, _> = match value { CelValue::List(item) => item.iter().cloned().map(compile_val).collect(), - CelValue::Map(item) => item.iter().map(|(key, _)| key).cloned().map(compile_val).collect(), + CelValue::Map(item) => item + .iter() + .map(|(key, _)| key) + .cloned() + .map(compile_val) + .collect(), _ => unreachable!(), }; let collected = collected?; - if collected.iter().any(|(_, c)| matches!(c, CompiledExpr::Runtime(_))) { + if collected + .iter() + .any(|(_, c)| matches!(c, CompiledExpr::Runtime(_))) + { let collected = collected.into_iter().map(|(item, expr)| { let item = CompiledExpr::constant(item); quote! { @@ -161,11 +188,7 @@ impl Function for Filter { .into_iter() .filter_map(|(item, c)| match c { CompiledExpr::Constant(ConstantCompiledExpr { value }) => { - if value.to_bool() { - Some(item) - } else { - None - } + if value.to_bool() { Some(item) } else { None } } _ => unreachable!("all values must be constant"), }) @@ -173,10 +196,12 @@ impl Function for Filter { ))) } } - CompiledExpr::Constant(ConstantCompiledExpr { value }) => Err(CompileError::TypeConversion { - ty: Box::new(CelType::CelValue), - message: format!("{value:?} cannot be iterated over"), - }), + CompiledExpr::Constant(ConstantCompiledExpr { value }) => { + Err(CompileError::TypeConversion { + ty: Box::new(CelType::CelValue), + message: format!("{value:?} cannot be iterated over"), + }) + } } } } @@ -198,7 +223,11 @@ mod tests { #[test] fn test_filter_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(Filter.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( @@ -321,7 +350,11 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_filter_runtime_map() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let mut compiler = Compiler::new(®istry); let string_value = CompiledExpr::runtime( @@ -338,7 +371,10 @@ mod tests { .compile(CompilerCtx::new( compiler.child(), Some(string_value), - &[cel_parser::parse("x").unwrap(), cel_parser::parse("input[x] >= 1").unwrap()], + &[ + cel_parser::parse("x").unwrap(), + cel_parser::parse("input[x] >= 1").unwrap(), + ], )) .unwrap(); @@ -375,11 +411,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_filter_runtime_repeated() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let string_value = CompiledExpr::runtime( - CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated(ProtoValueType::Int32))), + CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated( + ProtoValueType::Int32, + ))), parse_quote!(input), ); @@ -387,7 +429,10 @@ mod tests { .compile(CompilerCtx::new( compiler.child(), Some(string_value), - &[cel_parser::parse("x").unwrap(), cel_parser::parse("x >= 1").unwrap()], + &[ + cel_parser::parse("x").unwrap(), + cel_parser::parse("x >= 1").unwrap(), + ], )) .unwrap(); @@ -417,7 +462,11 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_filter_runtime_cel_value() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let string_value = CompiledExpr::runtime(CelType::CelValue, parse_quote!(input)); @@ -426,7 +475,10 @@ mod tests { .compile(CompilerCtx::new( compiler.child(), Some(string_value), - &[cel_parser::parse("x").unwrap(), cel_parser::parse("x > 5").unwrap()], + &[ + cel_parser::parse("x").unwrap(), + cel_parser::parse("x > 5").unwrap(), + ], )) .unwrap(); @@ -460,20 +512,31 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_filter_const_requires_runtime() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let list_value = CompiledExpr::constant(CelValue::List( - [CelValueConv::conv(5), CelValueConv::conv(0), CelValueConv::conv(1)] - .into_iter() - .collect(), + [ + CelValueConv::conv(5), + CelValueConv::conv(0), + CelValueConv::conv(1), + ] + .into_iter() + .collect(), )); let output = Filter .compile(CompilerCtx::new( compiler.child(), Some(list_value), - &[cel_parser::parse("x").unwrap(), cel_parser::parse("dyn(x >= 1)").unwrap()], + &[ + cel_parser::parse("x").unwrap(), + cel_parser::parse("dyn(x >= 1)").unwrap(), + ], )) .unwrap(); diff --git a/tinc-build/src/codegen/cel/functions/has.rs b/tinc-build/src/codegen/cel/functions/has.rs index 7e0975c..1faca11 100644 --- a/tinc-build/src/codegen/cel/functions/has.rs +++ b/tinc-build/src/codegen/cel/functions/has.rs @@ -43,7 +43,11 @@ mod tests { #[test] fn test_has_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let mut compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(Has.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( diff --git a/tinc-build/src/codegen/cel/functions/int.rs b/tinc-build/src/codegen/cel/functions/int.rs index 2e97d6c..62d18c5 100644 --- a/tinc-build/src/codegen/cel/functions/int.rs +++ b/tinc-build/src/codegen/cel/functions/int.rs @@ -2,7 +2,9 @@ use syn::parse_quote; use tinc_cel::CelValue; use super::Function; -use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr}; +use crate::codegen::cel::compiler::{ + CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr, +}; use crate::codegen::cel::types::CelType; #[derive(Debug, Clone, Default)] @@ -54,7 +56,11 @@ mod tests { #[test] fn test_int_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(Int.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( @@ -94,11 +100,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_int_runtime() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); - let string_value = - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ProtoValueType::String)), parse_quote!(input)); + let string_value = CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ProtoValueType::String)), + parse_quote!(input), + ); let output = Int .compile(CompilerCtx::new(compiler.child(), Some(string_value), &[])) diff --git a/tinc-build/src/codegen/cel/functions/is_email.rs b/tinc-build/src/codegen/cel/functions/is_email.rs index 5dbe773..2f7368e 100644 --- a/tinc-build/src/codegen/cel/functions/is_email.rs +++ b/tinc-build/src/codegen/cel/functions/is_email.rs @@ -2,7 +2,9 @@ use syn::parse_quote; use tinc_cel::CelValue; use super::Function; -use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr}; +use crate::codegen::cel::compiler::{ + CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, +}; use crate::codegen::cel::types::CelType; use crate::types::{ProtoType, ProtoValueType}; @@ -62,7 +64,11 @@ mod tests { #[test] fn test_is_email_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(IsEmail.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( @@ -112,11 +118,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_is_email_runtime() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); - let string_value = - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ProtoValueType::String)), parse_quote!(input)); + let string_value = CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ProtoValueType::String)), + parse_quote!(input), + ); let output = IsEmail .compile(CompilerCtx::new(compiler.child(), Some(string_value), &[])) diff --git a/tinc-build/src/codegen/cel/functions/is_hostname.rs b/tinc-build/src/codegen/cel/functions/is_hostname.rs index b108f35..89d2c62 100644 --- a/tinc-build/src/codegen/cel/functions/is_hostname.rs +++ b/tinc-build/src/codegen/cel/functions/is_hostname.rs @@ -2,7 +2,9 @@ use syn::parse_quote; use tinc_cel::CelValue; use super::Function; -use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr}; +use crate::codegen::cel::compiler::{ + CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, +}; use crate::codegen::cel::types::CelType; use crate::types::{ProtoType, ProtoValueType}; @@ -62,7 +64,11 @@ mod tests { #[test] fn test_is_hostname_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(IsHostname.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( @@ -112,11 +118,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_is_hostname_runtime() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); - let string_value = - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ProtoValueType::String)), parse_quote!(input)); + let string_value = CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ProtoValueType::String)), + parse_quote!(input), + ); let output = IsHostname .compile(CompilerCtx::new(compiler.child(), Some(string_value), &[])) diff --git a/tinc-build/src/codegen/cel/functions/is_inf.rs b/tinc-build/src/codegen/cel/functions/is_inf.rs index 9c94d62..fd20dc1 100644 --- a/tinc-build/src/codegen/cel/functions/is_inf.rs +++ b/tinc-build/src/codegen/cel/functions/is_inf.rs @@ -2,7 +2,9 @@ use syn::parse_quote; use tinc_cel::CelValue; use super::Function; -use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr}; +use crate::codegen::cel::compiler::{ + CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, +}; use crate::codegen::cel::types::CelType; use crate::types::{ProtoType, ProtoValueType}; @@ -62,7 +64,11 @@ mod tests { #[test] fn test_is_inf_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(IsInf.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( @@ -112,11 +118,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_is_inf_runtime() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); - let double_value = - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ProtoValueType::Double)), parse_quote!(input)); + let double_value = CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ProtoValueType::Double)), + parse_quote!(input), + ); let output = IsInf .compile(CompilerCtx::new(compiler.child(), Some(double_value), &[])) diff --git a/tinc-build/src/codegen/cel/functions/is_ipv4.rs b/tinc-build/src/codegen/cel/functions/is_ipv4.rs index 00f472a..b23b9b6 100644 --- a/tinc-build/src/codegen/cel/functions/is_ipv4.rs +++ b/tinc-build/src/codegen/cel/functions/is_ipv4.rs @@ -2,7 +2,9 @@ use syn::parse_quote; use tinc_cel::CelValue; use super::Function; -use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr}; +use crate::codegen::cel::compiler::{ + CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, +}; use crate::codegen::cel::types::CelType; use crate::types::{ProtoType, ProtoValueType}; @@ -62,7 +64,11 @@ mod tests { #[test] fn test_is_ipv4_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(IsIpv4.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( @@ -112,11 +118,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_is_ipv4_runtime() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); - let string_value = - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ProtoValueType::String)), parse_quote!(input)); + let string_value = CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ProtoValueType::String)), + parse_quote!(input), + ); let output = IsIpv4 .compile(CompilerCtx::new(compiler.child(), Some(string_value), &[])) diff --git a/tinc-build/src/codegen/cel/functions/is_ipv6.rs b/tinc-build/src/codegen/cel/functions/is_ipv6.rs index 23ad6ed..6c1cc53 100644 --- a/tinc-build/src/codegen/cel/functions/is_ipv6.rs +++ b/tinc-build/src/codegen/cel/functions/is_ipv6.rs @@ -2,7 +2,9 @@ use syn::parse_quote; use tinc_cel::CelValue; use super::Function; -use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr}; +use crate::codegen::cel::compiler::{ + CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, +}; use crate::codegen::cel::types::CelType; use crate::types::{ProtoType, ProtoValueType}; @@ -62,7 +64,11 @@ mod tests { #[test] fn test_is_ipv6_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(IsIpv6.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( @@ -112,11 +118,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_is_ipv6_runtime() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); - let string_value = - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ProtoValueType::String)), parse_quote!(input)); + let string_value = CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ProtoValueType::String)), + parse_quote!(input), + ); let output = IsIpv6 .compile(CompilerCtx::new(compiler.child(), Some(string_value), &[])) diff --git a/tinc-build/src/codegen/cel/functions/is_nan.rs b/tinc-build/src/codegen/cel/functions/is_nan.rs index 021a13c..3fb3612 100644 --- a/tinc-build/src/codegen/cel/functions/is_nan.rs +++ b/tinc-build/src/codegen/cel/functions/is_nan.rs @@ -2,7 +2,9 @@ use syn::parse_quote; use tinc_cel::CelValue; use super::Function; -use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr}; +use crate::codegen::cel::compiler::{ + CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, +}; use crate::codegen::cel::types::CelType; use crate::types::{ProtoType, ProtoValueType}; @@ -62,7 +64,11 @@ mod tests { #[test] fn test_is_nan_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(IsNaN.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( @@ -112,11 +118,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_is_nan_runtime() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); - let double_value = - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ProtoValueType::Double)), parse_quote!(input)); + let double_value = CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ProtoValueType::Double)), + parse_quote!(input), + ); let output = IsNaN .compile(CompilerCtx::new(compiler.child(), Some(double_value), &[])) diff --git a/tinc-build/src/codegen/cel/functions/is_ulid.rs b/tinc-build/src/codegen/cel/functions/is_ulid.rs index 7d37d0e..f49dae3 100644 --- a/tinc-build/src/codegen/cel/functions/is_ulid.rs +++ b/tinc-build/src/codegen/cel/functions/is_ulid.rs @@ -2,7 +2,9 @@ use syn::parse_quote; use tinc_cel::CelValue; use super::Function; -use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr}; +use crate::codegen::cel::compiler::{ + CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, +}; use crate::codegen::cel::types::CelType; use crate::types::{ProtoType, ProtoValueType}; @@ -62,7 +64,11 @@ mod tests { #[test] fn test_is_ulid_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(IsUlid.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( @@ -112,11 +118,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_is_ulid_runtime() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); - let string_value = - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ProtoValueType::String)), parse_quote!(input)); + let string_value = CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ProtoValueType::String)), + parse_quote!(input), + ); let output = IsUlid .compile(CompilerCtx::new(compiler.child(), Some(string_value), &[])) diff --git a/tinc-build/src/codegen/cel/functions/is_uri.rs b/tinc-build/src/codegen/cel/functions/is_uri.rs index 705da1e..3069cd4 100644 --- a/tinc-build/src/codegen/cel/functions/is_uri.rs +++ b/tinc-build/src/codegen/cel/functions/is_uri.rs @@ -2,7 +2,9 @@ use syn::parse_quote; use tinc_cel::CelValue; use super::Function; -use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr}; +use crate::codegen::cel::compiler::{ + CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, +}; use crate::codegen::cel::types::CelType; use crate::types::{ProtoType, ProtoValueType}; @@ -62,7 +64,11 @@ mod tests { #[test] fn test_is_uri_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(IsUri.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( @@ -124,11 +130,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_is_uri_runtime() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); - let string_value = - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ProtoValueType::String)), parse_quote!(input)); + let string_value = CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ProtoValueType::String)), + parse_quote!(input), + ); let output = IsUri .compile(CompilerCtx::new(compiler.child(), Some(string_value), &[])) diff --git a/tinc-build/src/codegen/cel/functions/is_uuid.rs b/tinc-build/src/codegen/cel/functions/is_uuid.rs index bc08c33..51aef2c 100644 --- a/tinc-build/src/codegen/cel/functions/is_uuid.rs +++ b/tinc-build/src/codegen/cel/functions/is_uuid.rs @@ -2,7 +2,9 @@ use syn::parse_quote; use tinc_cel::CelValue; use super::Function; -use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr}; +use crate::codegen::cel::compiler::{ + CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, +}; use crate::codegen::cel::types::CelType; use crate::types::{ProtoType, ProtoValueType}; @@ -62,7 +64,11 @@ mod tests { #[test] fn test_is_uuid_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(IsUuid.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( @@ -112,11 +118,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_is_uuid_runtime() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); - let string_value = - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ProtoValueType::String)), parse_quote!(input)); + let string_value = CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ProtoValueType::String)), + parse_quote!(input), + ); let output = IsUuid .compile(CompilerCtx::new(compiler.child(), Some(string_value), &[])) diff --git a/tinc-build/src/codegen/cel/functions/map.rs b/tinc-build/src/codegen/cel/functions/map.rs index 01a0cbb..c13195a 100644 --- a/tinc-build/src/codegen/cel/functions/map.rs +++ b/tinc-build/src/codegen/cel/functions/map.rs @@ -4,7 +4,9 @@ use syn::parse_quote; use tinc_cel::CelValue; use super::Function; -use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr}; +use crate::codegen::cel::compiler::{ + CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr, +}; use crate::codegen::cel::types::CelType; use crate::types::{ProtoModifiedValueType, ProtoType, ProtoValueType}; @@ -45,7 +47,10 @@ impl Function for Map { } let cel_parser::Expression::Ident(variable) = &ctx.args[0] else { - return Err(CompileError::syntax("first argument must be an ident", self)); + return Err(CompileError::syntax( + "first argument must be an ident", + self, + )); }; match this { @@ -54,14 +59,20 @@ impl Function for Map { match ty { CelType::CelValue => { - child_ctx.add_variable(variable, CompiledExpr::runtime(CelType::CelValue, parse_quote!(item))); + child_ctx.add_variable( + variable, + CompiledExpr::runtime(CelType::CelValue, parse_quote!(item)), + ); } CelType::Proto(ProtoType::Modified( ProtoModifiedValueType::Repeated(ty) | ProtoModifiedValueType::Map(ty, _), )) => { child_ctx.add_variable( variable, - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ty.clone())), parse_quote!(item)), + CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ty.clone())), + parse_quote!(item), + ), ); } v => { @@ -87,9 +98,9 @@ impl Function for Map { CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Map(_, _))) => { native_impl(quote!((#expr).keys()), parse_quote!(item), arg) } - CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated(_))) => { - native_impl(quote!((#expr).iter()), parse_quote!(item), arg) - } + CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated( + _, + ))) => native_impl(quote!((#expr).iter()), parse_quote!(item), arg), _ => unreachable!(), }, )) @@ -107,12 +118,20 @@ impl Function for Map { let collected: Result, _> = match value { CelValue::List(item) => item.iter().cloned().map(compile_val).collect(), - CelValue::Map(item) => item.iter().map(|(key, _)| key).cloned().map(compile_val).collect(), + CelValue::Map(item) => item + .iter() + .map(|(key, _)| key) + .cloned() + .map(compile_val) + .collect(), _ => unreachable!(), }; let collected = collected?; - if collected.iter().any(|c| matches!(c, CompiledExpr::Runtime(_))) { + if collected + .iter() + .any(|c| matches!(c, CompiledExpr::Runtime(_))) + { Ok(CompiledExpr::runtime( CelType::Proto(ProtoType::Value(ProtoValueType::Bool)), native_impl(quote!([#(#collected),*]), parse_quote!(item), quote!(item)), @@ -129,10 +148,12 @@ impl Function for Map { ))) } } - CompiledExpr::Constant(ConstantCompiledExpr { value }) => Err(CompileError::TypeConversion { - ty: Box::new(CelType::CelValue), - message: format!("{value:?} cannot be iterated over"), - }), + CompiledExpr::Constant(ConstantCompiledExpr { value }) => { + Err(CompileError::TypeConversion { + ty: Box::new(CelType::CelValue), + message: format!("{value:?} cannot be iterated over"), + }) + } } } } @@ -154,7 +175,11 @@ mod tests { #[test] fn test_map_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(Map.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( @@ -297,7 +322,11 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_map_runtime_map() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let mut compiler = Compiler::new(®istry); let string_value = CompiledExpr::runtime( @@ -314,7 +343,10 @@ mod tests { .compile(CompilerCtx::new( compiler.child(), Some(string_value), - &[cel_parser::parse("x").unwrap(), cel_parser::parse("input[x] * 2").unwrap()], + &[ + cel_parser::parse("x").unwrap(), + cel_parser::parse("input[x] * 2").unwrap(), + ], )) .unwrap(); @@ -353,11 +385,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_map_runtime_repeated() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let string_value = CompiledExpr::runtime( - CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated(ProtoValueType::Int32))), + CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated( + ProtoValueType::Int32, + ))), parse_quote!(input), ); @@ -365,7 +403,10 @@ mod tests { .compile(CompilerCtx::new( compiler.child(), Some(string_value), - &[cel_parser::parse("x").unwrap(), cel_parser::parse("x * 100").unwrap()], + &[ + cel_parser::parse("x").unwrap(), + cel_parser::parse("x * 100").unwrap(), + ], )) .unwrap(); @@ -397,7 +438,11 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_map_runtime_cel_value() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let string_value = CompiledExpr::runtime(CelType::CelValue, parse_quote!(input)); @@ -406,7 +451,10 @@ mod tests { .compile(CompilerCtx::new( compiler.child(), Some(string_value), - &[cel_parser::parse("x").unwrap(), cel_parser::parse("x + 1").unwrap()], + &[ + cel_parser::parse("x").unwrap(), + cel_parser::parse("x + 1").unwrap(), + ], )) .unwrap(); @@ -443,20 +491,31 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_map_const_requires_runtime() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let list_value = CompiledExpr::constant(CelValue::List( - [CelValueConv::conv(5), CelValueConv::conv(0), CelValueConv::conv(1)] - .into_iter() - .collect(), + [ + CelValueConv::conv(5), + CelValueConv::conv(0), + CelValueConv::conv(1), + ] + .into_iter() + .collect(), )); let output = Map .compile(CompilerCtx::new( compiler.child(), Some(list_value), - &[cel_parser::parse("x").unwrap(), cel_parser::parse("dyn(x / 2)").unwrap()], + &[ + cel_parser::parse("x").unwrap(), + cel_parser::parse("dyn(x / 2)").unwrap(), + ], )) .unwrap(); diff --git a/tinc-build/src/codegen/cel/functions/matches.rs b/tinc-build/src/codegen/cel/functions/matches.rs index cfd6eb2..d0b05c3 100644 --- a/tinc-build/src/codegen/cel/functions/matches.rs +++ b/tinc-build/src/codegen/cel/functions/matches.rs @@ -2,7 +2,9 @@ use syn::parse_quote; use tinc_cel::CelValue; use super::Function; -use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr}; +use crate::codegen::cel::compiler::{ + CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, +}; use crate::codegen::cel::types::CelType; use crate::types::{ProtoType, ProtoValueType}; @@ -32,15 +34,22 @@ impl Function for Matches { value: CelValue::String(regex), }) = ctx.resolve(&ctx.args[0])?.into_cel()? else { - return Err(CompileError::syntax("regex must be known at compile time string", self)); + return Err(CompileError::syntax( + "regex must be known at compile time string", + self, + )); }; let regex = regex.as_ref(); if regex.is_empty() { - return Err(CompileError::syntax("regex cannot be an empty string", self)); + return Err(CompileError::syntax( + "regex cannot be an empty string", + self, + )); } - let re = regex::Regex::new(regex).map_err(|err| CompileError::syntax(format!("bad regex {err}"), self))?; + let re = regex::Regex::new(regex) + .map_err(|err| CompileError::syntax(format!("bad regex {err}"), self))?; let this = this.clone().into_cel()?; @@ -82,7 +91,11 @@ mod tests { #[test] fn test_matches_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(Matches.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( @@ -131,11 +144,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_matches_runtime_string() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); - let string_value = - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ProtoValueType::String)), parse_quote!(input)); + let string_value = CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ProtoValueType::String)), + parse_quote!(input), + ); let output = Matches .compile(CompilerCtx::new( diff --git a/tinc-build/src/codegen/cel/functions/size.rs b/tinc-build/src/codegen/cel/functions/size.rs index 224c911..31973cc 100644 --- a/tinc-build/src/codegen/cel/functions/size.rs +++ b/tinc-build/src/codegen/cel/functions/size.rs @@ -2,7 +2,9 @@ use syn::parse_quote; use tinc_cel::CelValue; use super::Function; -use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr}; +use crate::codegen::cel::compiler::{ + CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr, +}; use crate::codegen::cel::types::CelType; use crate::types::{ProtoModifiedValueType, ProtoType, ProtoValueType}; @@ -29,7 +31,10 @@ impl Function for Size { if let CompiledExpr::Runtime(RuntimeCompiledExpr { expr, - ty: CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated(_) | ProtoModifiedValueType::Map(_, _))), + ty: + CelType::Proto(ProtoType::Modified( + ProtoModifiedValueType::Repeated(_) | ProtoModifiedValueType::Map(_, _), + )), }) = &this { return Ok(CompiledExpr::runtime( @@ -41,7 +46,9 @@ impl Function for Size { } match this.into_cel()? { - CompiledExpr::Constant(ConstantCompiledExpr { value }) => Ok(CompiledExpr::constant(CelValue::cel_size(value)?)), + CompiledExpr::Constant(ConstantCompiledExpr { value }) => { + Ok(CompiledExpr::constant(CelValue::cel_size(value)?)) + } CompiledExpr::Runtime(RuntimeCompiledExpr { expr, .. }) => Ok(CompiledExpr::runtime( CelType::Proto(ProtoType::Value(ProtoValueType::UInt64)), parse_quote!(::tinc::__private::cel::CelValue::cel_size(#expr)?), @@ -66,7 +73,11 @@ mod tests { #[test] fn test_size_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(Size.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( @@ -106,11 +117,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_size_runtime() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); - let string_value = - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ProtoValueType::String)), parse_quote!(input)); + let string_value = CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ProtoValueType::String)), + parse_quote!(input), + ); let output = Size .compile(CompilerCtx::new(compiler.child(), Some(string_value), &[])) @@ -139,7 +156,11 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_size_runtime_map() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let input = CompiledExpr::runtime( @@ -150,7 +171,9 @@ mod tests { parse_quote!(input), ); - let output = Size.compile(CompilerCtx::new(compiler.child(), Some(input), &[])).unwrap(); + let output = Size + .compile(CompilerCtx::new(compiler.child(), Some(input), &[])) + .unwrap(); insta::assert_snapshot!(postcompile::compile_str!( postcompile::config! { @@ -188,11 +211,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_size_runtime_repeated() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); let string_value = CompiledExpr::runtime( - CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated(ProtoValueType::String))), + CelType::Proto(ProtoType::Modified(ProtoModifiedValueType::Repeated( + ProtoValueType::String, + ))), parse_quote!(input), ); diff --git a/tinc-build/src/codegen/cel/functions/starts_with.rs b/tinc-build/src/codegen/cel/functions/starts_with.rs index 40e9553..f6bb9b3 100644 --- a/tinc-build/src/codegen/cel/functions/starts_with.rs +++ b/tinc-build/src/codegen/cel/functions/starts_with.rs @@ -2,7 +2,9 @@ use syn::parse_quote; use tinc_cel::CelValue; use super::Function; -use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr}; +use crate::codegen::cel::compiler::{ + CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, +}; use crate::codegen::cel::types::CelType; use crate::types::{ProtoType, ProtoValueType}; @@ -35,7 +37,9 @@ impl Function for StartsWith { ( CompiledExpr::Constant(ConstantCompiledExpr { value: this }), CompiledExpr::Constant(ConstantCompiledExpr { value: arg }), - ) => Ok(CompiledExpr::constant(CelValue::cel_starts_with(this, arg)?)), + ) => Ok(CompiledExpr::constant(CelValue::cel_starts_with( + this, arg, + )?)), (this, arg) => Ok(CompiledExpr::runtime( CelType::Proto(ProtoType::Value(ProtoValueType::Bool)), parse_quote! { @@ -65,7 +69,11 @@ mod tests { #[test] fn test_starts_with_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(StartsWith.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( @@ -103,11 +111,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_starts_with_runtime() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); - let string_value = - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ProtoValueType::String)), parse_quote!(input)); + let string_value = CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ProtoValueType::String)), + parse_quote!(input), + ); let output = StartsWith .compile(CompilerCtx::new( diff --git a/tinc-build/src/codegen/cel/functions/string.rs b/tinc-build/src/codegen/cel/functions/string.rs index 601f5e9..588d89a 100644 --- a/tinc-build/src/codegen/cel/functions/string.rs +++ b/tinc-build/src/codegen/cel/functions/string.rs @@ -4,7 +4,8 @@ use tinc_cel::CelValue; use super::Function; use crate::codegen::cel::compiler::{ - CompileError, CompiledExpr, Compiler, CompilerCtx, CompilerTarget, ConstantCompiledExpr, RuntimeCompiledExpr, + CompileError, CompiledExpr, Compiler, CompilerCtx, CompilerTarget, ConstantCompiledExpr, + RuntimeCompiledExpr, }; use crate::codegen::cel::types::CelType; @@ -15,7 +16,10 @@ fn cel_to_string(ctx: &Compiler, value: &CelValue<'static>) -> CompiledExpr { match value { CelValue::List(list) => { let items: Vec<_> = list.iter().map(|item| cel_to_string(ctx, item)).collect(); - if items.iter().any(|item| matches!(item, CompiledExpr::Runtime(_))) { + if items + .iter() + .any(|item| matches!(item, CompiledExpr::Runtime(_))) + { CompiledExpr::runtime( CelType::CelValue, parse_quote!({ @@ -41,10 +45,9 @@ fn cel_to_string(ctx: &Compiler, value: &CelValue<'static>) -> CompiledExpr { .iter() .map(|(key, value)| (cel_to_string(ctx, key), cel_to_string(ctx, value))) .collect(); - if items - .iter() - .any(|(key, value)| matches!(key, CompiledExpr::Runtime(_)) || matches!(value, CompiledExpr::Runtime(_))) - { + if items.iter().any(|(key, value)| { + matches!(key, CompiledExpr::Runtime(_)) || matches!(value, CompiledExpr::Runtime(_)) + }) { let items = items.iter().map(|(key, value)| quote!((#key, #value))); CompiledExpr::runtime( CelType::CelValue, @@ -81,8 +84,12 @@ fn cel_to_string(ctx: &Compiler, value: &CelValue<'static>) -> CompiledExpr { let serde_name = &proto_enum.options.serde_name; match ctx.target() { - Some(CompilerTarget::Serde) => CompiledExpr::constant(CelValue::String(serde_name.clone().into())), - Some(CompilerTarget::Proto) => CompiledExpr::constant(CelValue::String(proto_name.clone().into())), + Some(CompilerTarget::Serde) => { + CompiledExpr::constant(CelValue::String(serde_name.clone().into())) + } + Some(CompilerTarget::Proto) => { + CompiledExpr::constant(CelValue::String(proto_name.clone().into())) + } None => CompiledExpr::runtime( CelType::CelValue, parse_quote! { @@ -123,7 +130,9 @@ impl Function for String { } match this.into_cel()? { - CompiledExpr::Constant(ConstantCompiledExpr { value }) => Ok(cel_to_string(&ctx, &value)), + CompiledExpr::Constant(ConstantCompiledExpr { value }) => { + Ok(cel_to_string(&ctx, &value)) + } CompiledExpr::Runtime(RuntimeCompiledExpr { expr, .. }) => Ok(CompiledExpr::runtime( CelType::CelValue, parse_quote!(::tinc::__private::cel::CelValue::cel_to_string(#expr)), @@ -148,7 +157,11 @@ mod tests { #[test] fn test_string_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(String.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( @@ -188,11 +201,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_string_runtime() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); - let string_value = - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ProtoValueType::String)), parse_quote!(input)); + let string_value = CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ProtoValueType::String)), + parse_quote!(input), + ); let output = String .compile(CompilerCtx::new(compiler.child(), Some(string_value), &[])) diff --git a/tinc-build/src/codegen/cel/functions/uint.rs b/tinc-build/src/codegen/cel/functions/uint.rs index f84765f..5afb981 100644 --- a/tinc-build/src/codegen/cel/functions/uint.rs +++ b/tinc-build/src/codegen/cel/functions/uint.rs @@ -2,7 +2,9 @@ use syn::parse_quote; use tinc_cel::CelValue; use super::Function; -use crate::codegen::cel::compiler::{CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr}; +use crate::codegen::cel::compiler::{ + CompileError, CompiledExpr, CompilerCtx, ConstantCompiledExpr, RuntimeCompiledExpr, +}; use crate::codegen::cel::types::CelType; #[derive(Debug, Clone, Default)] @@ -27,13 +29,17 @@ impl Function for UInt { } match this.into_cel()? { - CompiledExpr::Constant(ConstantCompiledExpr { value }) => Ok(CompiledExpr::Constant(ConstantCompiledExpr { - value: CelValue::cel_to_uint(value)?, - })), - CompiledExpr::Runtime(RuntimeCompiledExpr { expr, .. }) => Ok(CompiledExpr::Runtime(RuntimeCompiledExpr { - ty: CelType::CelValue, - expr: parse_quote!(::tinc::__private::cel::CelValue::cel_to_uint(#expr)?), - })), + CompiledExpr::Constant(ConstantCompiledExpr { value }) => { + Ok(CompiledExpr::Constant(ConstantCompiledExpr { + value: CelValue::cel_to_uint(value)?, + })) + } + CompiledExpr::Runtime(RuntimeCompiledExpr { expr, .. }) => { + Ok(CompiledExpr::Runtime(RuntimeCompiledExpr { + ty: CelType::CelValue, + expr: parse_quote!(::tinc::__private::cel::CelValue::cel_to_uint(#expr)?), + })) + } } } } @@ -54,7 +60,11 @@ mod tests { #[test] fn test_uint_syntax() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); insta::assert_debug_snapshot!(UInt.compile(CompilerCtx::new(compiler.child(), None, &[])), @r#" Err( @@ -94,11 +104,17 @@ mod tests { #[test] #[cfg(not(valgrind))] fn test_uint_runtime() { - let registry = ProtoTypeRegistry::new(crate::Mode::Prost, ExternPaths::new(crate::Mode::Prost), PathSet::default()); + let registry = ProtoTypeRegistry::new( + crate::Mode::Prost, + ExternPaths::new(crate::Mode::Prost), + PathSet::default(), + ); let compiler = Compiler::new(®istry); - let string_value = - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(ProtoValueType::String)), parse_quote!(input)); + let string_value = CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(ProtoValueType::String)), + parse_quote!(input), + ); let output = UInt .compile(CompilerCtx::new(compiler.child(), Some(string_value), &[])) diff --git a/tinc-build/src/codegen/config.rs b/tinc-build/src/codegen/config.rs index 4937f84..7c0fae1 100644 --- a/tinc-build/src/codegen/config.rs +++ b/tinc-build/src/codegen/config.rs @@ -37,7 +37,10 @@ impl EnumConfig { self.container_attributes.iter() } - pub(crate) fn variant_attributes(&self, variant: &str) -> impl Iterator { + pub(crate) fn variant_attributes( + &self, + variant: &str, + ) -> impl Iterator { self.variant_attributes.get(variant).into_iter().flatten() } @@ -50,7 +53,10 @@ impl EnumConfig { } pub(crate) fn variant_attribute(&mut self, variant: &str, attr: syn::Attribute) { - self.variant_attributes.entry(variant.to_owned()).or_default().push(attr); + self.variant_attributes + .entry(variant.to_owned()) + .or_default() + .push(attr); } } @@ -75,7 +81,9 @@ impl MessageConfig { } pub(crate) fn oneof_configs(&self) -> impl Iterator { - self.oneof_attributes.iter().map(|(name, config)| (name.as_str(), config)) + self.oneof_attributes + .iter() + .map(|(name, config)| (name.as_str(), config)) } pub(crate) fn attribute(&mut self, attr: syn::Attribute) { @@ -83,7 +91,10 @@ impl MessageConfig { } pub(crate) fn field_attribute(&mut self, field: &str, attr: syn::Attribute) { - self.field_attributes.entry(field.to_owned()).or_default().push(attr); + self.field_attributes + .entry(field.to_owned()) + .or_default() + .push(attr); } pub(crate) fn oneof_config(&mut self, oneof: &str) -> &mut OneofConfig { @@ -115,6 +126,9 @@ impl OneofConfig { } pub(crate) fn field_attribute(&mut self, field: &str, attr: syn::Attribute) { - self.field_attributes.entry(field.to_owned()).or_default().push(attr); + self.field_attributes + .entry(field.to_owned()) + .or_default() + .push(attr); } } diff --git a/tinc-build/src/codegen/prost_sanatize.rs b/tinc-build/src/codegen/prost_sanatize.rs index 32c6a60..ec2ca57 100644 --- a/tinc-build/src/codegen/prost_sanatize.rs +++ b/tinc-build/src/codegen/prost_sanatize.rs @@ -44,7 +44,12 @@ pub(crate) fn strip_enum_prefix(prefix: &str, name: &str) -> String { // If the next character after the stripped prefix is not // uppercase, then it means that we didn't have a true prefix - // for example, "Foo" should not be stripped from "Foobar". - let stripped = if stripped.chars().next().map(char::is_uppercase).unwrap_or(false) { + let stripped = if stripped + .chars() + .next() + .map(char::is_uppercase) + .unwrap_or(false) + { stripped } else { name diff --git a/tinc-build/src/codegen/serde.rs b/tinc-build/src/codegen/serde.rs index d86bf98..8f2ca3a 100644 --- a/tinc-build/src/codegen/serde.rs +++ b/tinc-build/src/codegen/serde.rs @@ -7,8 +7,9 @@ use super::cel::compiler::{CompiledExpr, Compiler}; use super::cel::types::CelType; use super::cel::{CelExpression, eval_message_fmt, functions}; use crate::types::{ - ProtoEnumType, ProtoFieldOptions, ProtoFieldSerdeOmittable, ProtoMessageField, ProtoMessageType, ProtoModifiedValueType, - ProtoOneOfType, ProtoType, ProtoTypeRegistry, ProtoValueType, ProtoVisibility, Tagged, + ProtoEnumType, ProtoFieldOptions, ProtoFieldSerdeOmittable, ProtoMessageField, + ProtoMessageType, ProtoModifiedValueType, ProtoOneOfType, ProtoType, ProtoTypeRegistry, + ProtoValueType, ProtoVisibility, Tagged, }; fn handle_oneof( @@ -215,8 +216,12 @@ fn handle_oneof( .to_string(); if field.options.visibility.has_output() { - let serialize_with = format!("::tinc::__private::serialize_enum::<{path_str}, _, _>"); - oneof_config.field_attribute(field_name, parse_quote!(#[serde(serialize_with = #serialize_with)])); + let serialize_with = + format!("::tinc::__private::serialize_enum::<{path_str}, _, _>"); + oneof_config.field_attribute( + field_name, + parse_quote!(#[serde(serialize_with = #serialize_with)]), + ); } oneof_config.field_attribute(field_name, parse_quote!(#[tinc(enum = #path_str)])); @@ -238,7 +243,10 @@ fn handle_oneof( ); } if field.options.visibility.has_input() { - oneof_config.field_attribute(field_name, parse_quote!(#[tinc(with_non_finite_values)])); + oneof_config.field_attribute( + field_name, + parse_quote!(#[tinc(with_non_finite_values)]), + ); } } } @@ -246,7 +254,9 @@ fn handle_oneof( } } - let message = registry.get_message(&oneof.message).expect("message not found"); + let message = registry + .get_message(&oneof.message) + .expect("message not found"); let oneof_path = oneof.rust_path(&message.package); let oneof_ident = oneof_path.segments.last().unwrap().ident.clone(); @@ -384,16 +394,22 @@ fn handle_message_field( message_config.field_attribute(field_name, parse_quote!(#[serde(rename = #serde_name)])); - let message = registry.get_message(&field.message).expect("message not found"); + let message = registry + .get_message(&field.message) + .expect("message not found"); let ident = quote::format_ident!("__field_{field_name}"); if field.options.flatten { let flattened_ty_path = match &field.ty { - ProtoType::Modified(ProtoModifiedValueType::Optional(ProtoValueType::Message(path))) - | ProtoType::Value(ProtoValueType::Message(path)) => { - registry.resolve_rust_path(&message.package, path).expect("message not found") + ProtoType::Modified(ProtoModifiedValueType::Optional(ProtoValueType::Message( + path, + ))) + | ProtoType::Value(ProtoValueType::Message(path)) => registry + .resolve_rust_path(&message.package, path) + .expect("message not found"), + ProtoType::Modified(ProtoModifiedValueType::OneOf(oneof)) => { + oneof.rust_path(&message.package) } - ProtoType::Modified(ProtoModifiedValueType::OneOf(oneof)) => oneof.rust_path(&message.package), _ => anyhow::bail!("flattened fields must be messages or oneofs"), }; @@ -435,7 +451,10 @@ fn handle_message_field( } if field.options.visibility.has_output() { - if matches!(field.options.serde_omittable, ProtoFieldSerdeOmittable::True) { + if matches!( + field.options.serde_omittable, + ProtoFieldSerdeOmittable::True + ) { message_config.field_attribute( field_name, parse_quote!(#[serde(skip_serializing_if = "::tinc::__private::serde_ser_skip_default")]), @@ -454,8 +473,12 @@ fn handle_message_field( .to_string(); if field.options.visibility.has_output() { - let serialize_with = format!("::tinc::__private::serialize_enum::<{path_str}, _, _>"); - message_config.field_attribute(field_name, parse_quote!(#[serde(serialize_with = #serialize_with)])); + let serialize_with = + format!("::tinc::__private::serialize_enum::<{path_str}, _, _>"); + message_config.field_attribute( + field_name, + parse_quote!(#[serde(serialize_with = #serialize_with)]), + ); } message_config.field_attribute(field_name, parse_quote!(#[tinc(enum = #path_str)])); @@ -477,7 +500,8 @@ fn handle_message_field( ); } if field.options.visibility.has_input() { - message_config.field_attribute(field_name, parse_quote!(#[tinc(with_non_finite_values)])); + message_config + .field_attribute(field_name, parse_quote!(#[tinc(with_non_finite_values)])); } } } @@ -485,7 +509,13 @@ fn handle_message_field( } if let ProtoType::Modified(ProtoModifiedValueType::OneOf(oneof)) = &field.ty { - handle_oneof(package, field_name, oneof, registry, field.options.visibility)?; + handle_oneof( + package, + field_name, + oneof, + registry, + field.options.visibility, + )?; } let field_ident = field.rust_ident(); @@ -500,8 +530,10 @@ fn handle_message_field( // When a field is not nullable but prost generates an option, we need to // remove the option before deserializing otherwise null will be a valid input. - if matches!(field.ty, ProtoType::Modified(ProtoModifiedValueType::Optional(_))) - && (!field.options.nullable || field.options.flatten) + if matches!( + field.ty, + ProtoType::Modified(ProtoModifiedValueType::Optional(_)) + ) && (!field.options.nullable || field.options.flatten) { tracker = quote! { (#tracker).get_or_insert_default() @@ -559,7 +591,11 @@ fn handle_message_field( quote! {} }; - let missing = if matches!(field.options.serde_omittable, ProtoFieldSerdeOmittable::False) && !field.options.flatten { + let missing = if matches!( + field.options.serde_omittable, + ProtoFieldSerdeOmittable::False + ) && !field.options.flatten + { quote! { ::tinc::__private::report_tracked_error( ::tinc::__private::TrackedError::missing_field(), @@ -570,7 +606,10 @@ fn handle_message_field( }; let mut tracker_access = quote!(tracker.and_then(|t| t.#field_ident.as_ref())); - if matches!(field.ty, ProtoType::Modified(ProtoModifiedValueType::Optional(_))) { + if matches!( + field.ty, + ProtoType::Modified(ProtoModifiedValueType::Optional(_)) + ) { tracker_access = quote!(#tracker_access.and_then(|t| t.as_ref())) } @@ -643,8 +682,12 @@ fn cel_expressions( { let mut compiler = compiler.child(); let (value_match, field_type) = match ty { - ProtoType::Modified(ProtoModifiedValueType::Optional(ty)) => (quote!(Some(value)), ProtoType::Value(ty.clone())), - ty @ ProtoType::Modified(ProtoModifiedValueType::OneOf(_)) => (quote!(Some(value)), ty.clone()), + ProtoType::Modified(ProtoModifiedValueType::Optional(ty)) => { + (quote!(Some(value)), ProtoType::Value(ty.clone())) + } + ty @ ProtoType::Modified(ProtoModifiedValueType::OneOf(_)) => { + (quote!(Some(value)), ty.clone()) + } _ => (quote!(value), ty.clone()), }; @@ -656,7 +699,8 @@ fn cel_expressions( let recursive_validate = matches!( field_type, - ProtoType::Value(ProtoValueType::Message(_)) | ProtoType::Modified(ProtoModifiedValueType::OneOf(_)) + ProtoType::Value(ProtoValueType::Message(_)) + | ProtoType::Modified(ProtoModifiedValueType::OneOf(_)) ); compiler.add_variable( @@ -688,7 +732,9 @@ fn cel_expressions( if !options.nullable && matches!( &ty, - ProtoType::Modified(ProtoModifiedValueType::Optional(_) | ProtoModifiedValueType::OneOf(_)) + ProtoType::Modified( + ProtoModifiedValueType::Optional(_) | ProtoModifiedValueType::OneOf(_) + ) ) { cel_validation_fn.push(quote! {{ @@ -716,7 +762,10 @@ fn cel_expressions( compiler.add_variable( "input", - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(key.clone())), parse_quote!(key)), + CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(key.clone())), + parse_quote!(key), + ), ); options .cel_exprs @@ -735,7 +784,10 @@ fn cel_expressions( } compiler.add_variable( "input", - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(value.clone())), parse_quote!(value)), + CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(value.clone())), + parse_quote!(value), + ), ); options .cel_exprs @@ -765,7 +817,8 @@ fn cel_expressions( }}); } ProtoType::Modified(ProtoModifiedValueType::Repeated(item)) - if !options.cel_exprs.repeated_item.is_empty() || matches!(item, ProtoValueType::Message(_)) => + if !options.cel_exprs.repeated_item.is_empty() + || matches!(item, ProtoValueType::Message(_)) => { let is_message = matches!(item, ProtoValueType::Message(_)); let mut compiler = compiler.child(); @@ -774,7 +827,10 @@ fn cel_expressions( } compiler.add_variable( "input", - CompiledExpr::runtime(CelType::Proto(ProtoType::Value(item.clone())), parse_quote!(item)), + CompiledExpr::runtime( + CelType::Proto(ProtoType::Value(item.clone())), + parse_quote!(item), + ), ); let mut exprs = options @@ -855,7 +911,9 @@ pub(super) fn handle_message( ctx.add_variable( "input", CompiledExpr::runtime( - CelType::Proto(ProtoType::Value(ProtoValueType::Message(message.full_name.clone()))), + CelType::Proto(ProtoType::Value(ProtoValueType::Message( + message.full_name.clone(), + ))), parse_quote!(___input), ), ); @@ -866,10 +924,14 @@ pub(super) fn handle_message( if let Some(this) = expr.this.clone() { expr_ctx.add_variable("this", CompiledExpr::constant(this)); } - let parsed = cel_parser::parse(&expr.expression).context("message-level cel expression parse")?; - let resolved = expr_ctx.resolve(&parsed).context("message-level cel expression")?; + let parsed = cel_parser::parse(&expr.expression) + .context("message-level cel expression parse")?; + let resolved = expr_ctx + .resolve(&parsed) + .context("message-level cel expression")?; let expr_str = &expr.expression; - let message_str = eval_message_fmt(&message.full_name, &expr.message, &expr_ctx).context("message-level cel message")?; + let message_str = eval_message_fmt(&message.full_name, &expr.message, &expr_ctx) + .context("message-level cel message")?; message_cel_exprs.push(quote! { if !::tinc::__private::cel::to_bool({ @@ -988,7 +1050,11 @@ pub(super) fn handle_message( Ok(()) } -pub(super) fn handle_enum(enum_: &ProtoEnumType, package: &mut Package, registry: &ProtoTypeRegistry) -> anyhow::Result<()> { +pub(super) fn handle_enum( + enum_: &ProtoEnumType, + package: &mut Package, + registry: &ProtoTypeRegistry, +) -> anyhow::Result<()> { let enum_path = registry .resolve_rust_path(&enum_.package, &enum_.full_name) .expect("enum not found"); @@ -996,11 +1062,14 @@ pub(super) fn handle_enum(enum_: &ProtoEnumType, package: &mut Package, registry let enum_config = package.enum_config(&enum_.full_name); if enum_.options.repr_enum { - enum_config.attribute(parse_quote!(#[derive(::tinc::reexports::serde_repr::Serialize_repr)])); - enum_config.attribute(parse_quote!(#[derive(::tinc::reexports::serde_repr::Deserialize_repr)])); + enum_config + .attribute(parse_quote!(#[derive(::tinc::reexports::serde_repr::Serialize_repr)])); + enum_config + .attribute(parse_quote!(#[derive(::tinc::reexports::serde_repr::Deserialize_repr)])); } else { enum_config.attribute(parse_quote!(#[derive(::tinc::reexports::serde_derive::Serialize)])); - enum_config.attribute(parse_quote!(#[derive(::tinc::reexports::serde_derive::Deserialize)])); + enum_config + .attribute(parse_quote!(#[derive(::tinc::reexports::serde_derive::Deserialize)])); } enum_config.attribute(parse_quote!(#[serde(crate = "::tinc::reexports::serde")])); diff --git a/tinc-build/src/codegen/service.rs b/tinc-build/src/codegen/service.rs index 50de213..7e16f32 100644 --- a/tinc-build/src/codegen/service.rs +++ b/tinc-build/src/codegen/service.rs @@ -9,8 +9,8 @@ use tinc_pb_prost::http_endpoint_options; use super::Package; use super::utils::{field_ident_from_str, type_ident_from_str}; use crate::types::{ - Comments, ProtoPath, ProtoService, ProtoServiceMethod, ProtoServiceMethodEndpoint, ProtoServiceMethodIo, - ProtoTypeRegistry, ProtoValueType, + Comments, ProtoPath, ProtoService, ProtoServiceMethod, ProtoServiceMethodEndpoint, + ProtoServiceMethodIo, ProtoTypeRegistry, ProtoValueType, }; mod openapi; @@ -35,16 +35,30 @@ impl GeneratedMethod { components: &mut openapiv3_1::Components, ) -> anyhow::Result { let (http_method_oa, path) = match &endpoint.method { - tinc_pb_prost::http_endpoint_options::Method::Get(path) => (openapiv3_1::HttpMethod::Get, path), - tinc_pb_prost::http_endpoint_options::Method::Post(path) => (openapiv3_1::HttpMethod::Post, path), - tinc_pb_prost::http_endpoint_options::Method::Put(path) => (openapiv3_1::HttpMethod::Put, path), - tinc_pb_prost::http_endpoint_options::Method::Delete(path) => (openapiv3_1::HttpMethod::Delete, path), - tinc_pb_prost::http_endpoint_options::Method::Patch(path) => (openapiv3_1::HttpMethod::Patch, path), + tinc_pb_prost::http_endpoint_options::Method::Get(path) => { + (openapiv3_1::HttpMethod::Get, path) + } + tinc_pb_prost::http_endpoint_options::Method::Post(path) => { + (openapiv3_1::HttpMethod::Post, path) + } + tinc_pb_prost::http_endpoint_options::Method::Put(path) => { + (openapiv3_1::HttpMethod::Put, path) + } + tinc_pb_prost::http_endpoint_options::Method::Delete(path) => { + (openapiv3_1::HttpMethod::Delete, path) + } + tinc_pb_prost::http_endpoint_options::Method::Patch(path) => { + (openapiv3_1::HttpMethod::Patch, path) + } }; let full_path = match ( path.trim_matches('/'), - service.options.prefix.as_deref().map(|p| p.trim_matches('/')), + service + .options + .prefix + .as_deref() + .map(|p| p.trim_matches('/')), ) { ("", Some(prefix)) => format!("/{prefix}"), (path, None | Some("")) => format!("/{path}"), @@ -75,25 +89,38 @@ impl GeneratedMethod { openapi.parameters(params); let is_get_or_delete = matches!(http_method_oa, HttpMethod::Get | HttpMethod::Delete); - let request = endpoint.request.as_ref().and_then(|req| req.mode.clone()).unwrap_or_else(|| { - if is_get_or_delete { - http_endpoint_options::request::Mode::Query(http_endpoint_options::request::QueryParams::default()) - } else { - http_endpoint_options::request::Mode::Json(http_endpoint_options::request::JsonBody::default()) - } - }); + let request = endpoint + .request + .as_ref() + .and_then(|req| req.mode.clone()) + .unwrap_or_else(|| { + if is_get_or_delete { + http_endpoint_options::request::Mode::Query( + http_endpoint_options::request::QueryParams::default(), + ) + } else { + http_endpoint_options::request::Mode::Json( + http_endpoint_options::request::JsonBody::default(), + ) + } + }); let request_tokens = match request { - http_endpoint_options::request::Mode::Query(http_endpoint_options::request::QueryParams { field }) => { - let GeneratedParams { tokens, params } = generator.generate_query_parameter(field.as_deref())?; + http_endpoint_options::request::Mode::Query( + http_endpoint_options::request::QueryParams { field }, + ) => { + let GeneratedParams { tokens, params } = + generator.generate_query_parameter(field.as_deref())?; openapi.parameters(params); tokens } - http_endpoint_options::request::Mode::Binary(http_endpoint_options::request::BinaryBody { - field, - content_type_accepts, - content_type_field, - }) => { + http_endpoint_options::request::Mode::Binary( + http_endpoint_options::request::BinaryBody { + field, + content_type_accepts, + content_type_field, + }, + ) => { let GeneratedBody { tokens, body } = generator.generate_body( &method.cel, BodyMethod::Binary(content_type_accepts.as_deref()), @@ -103,23 +130,39 @@ impl GeneratedMethod { openapi.request_body = Some(body); tokens } - http_endpoint_options::request::Mode::Json(http_endpoint_options::request::JsonBody { field }) => { - let GeneratedBody { tokens, body } = - generator.generate_body(&method.cel, BodyMethod::Json, field.as_deref(), None)?; + http_endpoint_options::request::Mode::Json( + http_endpoint_options::request::JsonBody { field }, + ) => { + let GeneratedBody { tokens, body } = generator.generate_body( + &method.cel, + BodyMethod::Json, + field.as_deref(), + None, + )?; openapi.request_body = Some(body); tokens } - http_endpoint_options::request::Mode::Text(http_endpoint_options::request::TextBody { field }) => { - let GeneratedBody { tokens, body } = - generator.generate_body(&method.cel, BodyMethod::Text, field.as_deref(), None)?; + http_endpoint_options::request::Mode::Text( + http_endpoint_options::request::TextBody { field }, + ) => { + let GeneratedBody { tokens, body } = generator.generate_body( + &method.cel, + BodyMethod::Text, + field.as_deref(), + None, + )?; openapi.request_body = Some(body); tokens } }; let input_path = match &method.input { - ProtoServiceMethodIo::Single(input) => types.resolve_rust_path(package, input.proto_path()), - ProtoServiceMethodIo::Stream(_) => anyhow::bail!("currently streaming is not supported by tinc methods."), + ProtoServiceMethodIo::Single(input) => { + types.resolve_rust_path(package, input.proto_path()) + } + ProtoServiceMethodIo::Stream(_) => { + anyhow::bail!("currently streaming is not supported by tinc methods.") + } }; let service_method_name = field_ident_from_str(name); @@ -128,9 +171,11 @@ impl GeneratedMethod { .response .as_ref() .and_then(|resp| resp.mode.clone()) - .unwrap_or_else( - || http_endpoint_options::response::Mode::Json(http_endpoint_options::response::Json::default()), - ); + .unwrap_or_else(|| { + http_endpoint_options::response::Mode::Json( + http_endpoint_options::response::Json::default(), + ) + }); let response_ident = quote::format_ident!("response"); let builder_ident = quote::format_ident!("builder"); @@ -146,21 +191,23 @@ impl GeneratedMethod { body: response, tokens: response_tokens, } = match response { - http_endpoint_options::response::Mode::Binary(http_endpoint_options::response::Binary { - field, - content_type_accepts, - content_type_field, - }) => generator.generate_body( + http_endpoint_options::response::Mode::Binary( + http_endpoint_options::response::Binary { + field, + content_type_accepts, + content_type_field, + }, + ) => generator.generate_body( BodyMethod::Binary(content_type_accepts.as_deref()), field.as_deref(), content_type_field.as_deref(), )?, - http_endpoint_options::response::Mode::Json(http_endpoint_options::response::Json { field }) => { - generator.generate_body(BodyMethod::Json, field.as_deref(), None)? - } - http_endpoint_options::response::Mode::Text(http_endpoint_options::response::Text { field }) => { - generator.generate_body(BodyMethod::Text, field.as_deref(), None)? - } + http_endpoint_options::response::Mode::Json( + http_endpoint_options::response::Json { field }, + ) => generator.generate_body(BodyMethod::Json, field.as_deref(), None)?, + http_endpoint_options::response::Mode::Text( + http_endpoint_options::response::Text { field }, + ) => generator.generate_body(BodyMethod::Text, field.as_deref(), None)?, }; openapi.response("200", response); @@ -331,8 +378,10 @@ pub(super) fn handle_service( } let codec_path = if matches!(method.input.value_type(), ProtoValueType::Message(_)) { - let input_path = registry.resolve_rust_path(&package_name, method.input.value_type().proto_path()); - let output_path = registry.resolve_rust_path(&package_name, method.output.value_type().proto_path()); + let input_path = + registry.resolve_rust_path(&package_name, method.input.value_type().proto_path()); + let output_path = + registry.resolve_rust_path(&package_name, method.output.value_type().proto_path()); let codec_ident = format_ident!("{method_name}Codec"); method_codecs.push(quote! { #[derive(Debug, Clone, Default)] @@ -417,7 +466,9 @@ pub(super) fn handle_service( .tags(vec![openapi_tag]) .build(); - let json_openapi = openapi.to_json().context("invalid openapi schema generation")?; + let json_openapi = openapi + .to_json() + .context("invalid openapi schema generation")?; package.push_item(parse_quote! { /// This module was automatically generated by `tinc`. diff --git a/tinc-build/src/codegen/service/openapi.rs b/tinc-build/src/codegen/service/openapi.rs index 3cfe63a..a2a3b64 100644 --- a/tinc-build/src/codegen/service/openapi.rs +++ b/tinc-build/src/codegen/service/openapi.rs @@ -11,9 +11,15 @@ use tinc_cel::{CelValue, NumberTy}; use crate::codegen::cel::compiler::{CompiledExpr, Compiler, CompilerTarget, ConstantCompiledExpr}; use crate::codegen::cel::{CelExpression, CelExpressions, functions}; use crate::codegen::utils::field_ident_from_str; -use crate::types::{ProtoModifiedValueType, ProtoPath, ProtoType, ProtoTypeRegistry, ProtoValueType, ProtoWellKnownType}; - -fn cel_to_json(cel: &CelValue<'static>, type_registry: &ProtoTypeRegistry) -> anyhow::Result { +use crate::types::{ + ProtoModifiedValueType, ProtoPath, ProtoType, ProtoTypeRegistry, ProtoValueType, + ProtoWellKnownType, +}; + +fn cel_to_json( + cel: &CelValue<'static>, + type_registry: &ProtoTypeRegistry, +) -> anyhow::Result { match cel { CelValue::Null => Ok(serde_json::Value::Null), CelValue::Bool(b) => Ok(serde_json::Value::Bool(*b)), @@ -59,7 +65,13 @@ fn cel_to_json(cel: &CelValue<'static>, type_registry: &ProtoTypeRegistry) -> an .variants .values() .find(|v| v.value == cel_enum.value) - .with_context(|| format!("{} has no value for {}", cel_enum.tag.as_ref(), cel_enum.value))?; + .with_context(|| { + format!( + "{} has no value for {}", + cel_enum.tag.as_ref(), + cel_enum.value + ) + })?; Ok(serde_json::Value::from(variant.options.serde_name.clone())) } } @@ -75,7 +87,11 @@ fn parse_resolve(compiler: &Compiler, expr: &str) -> anyhow::Result anyhow::Result> { +fn handle_expr( + mut ctx: Compiler, + ty: &ProtoType, + expr: &CelExpression, +) -> anyhow::Result> { ctx.set_target(CompilerTarget::Serde); if let Some(this) = expr.this.clone() { @@ -205,13 +221,15 @@ fn input_field_getter_gen( is_optional = matches!( field.ty, - ProtoType::Modified(ProtoModifiedValueType::Optional(_) | ProtoModifiedValueType::OneOf(_)) + ProtoType::Modified( + ProtoModifiedValueType::Optional(_) | ProtoModifiedValueType::OneOf(_) + ) ); next_message = match &field.ty { ProtoType::Value(ProtoValueType::Message(path)) - | ProtoType::Modified(ProtoModifiedValueType::Optional(ProtoValueType::Message(path))) => { - Some(registry.get_message(path).unwrap()) - } + | ProtoType::Modified(ProtoModifiedValueType::Optional(ProtoValueType::Message( + path, + ))) => Some(registry.get_message(path).unwrap()), _ => None, } } @@ -252,7 +270,9 @@ fn output_field_getter_gen( cel = Some(&field.options.cel_exprs); let is_optional = matches!( field.ty, - ProtoType::Modified(ProtoModifiedValueType::Optional(_) | ProtoModifiedValueType::OneOf(_)) + ProtoType::Modified( + ProtoModifiedValueType::Optional(_) | ProtoModifiedValueType::OneOf(_) + ) ); mapping = match (is_optional, was_optional) { @@ -266,9 +286,9 @@ fn output_field_getter_gen( next_message = match &field.ty { ProtoType::Value(ProtoValueType::Message(path)) - | ProtoType::Modified(ProtoModifiedValueType::Optional(ProtoValueType::Message(path))) => { - Some(registry.get_message(path).unwrap()) - } + | ProtoType::Modified(ProtoModifiedValueType::Optional(ProtoValueType::Message( + path, + ))) => Some(registry.get_message(path).unwrap()), _ => None, } } @@ -331,7 +351,9 @@ fn path_struct( let match_single_ty = |ty: &ProtoValueType| { Some(match &ty { ProtoValueType::Enum(path) => { - let path = registry.resolve_rust_path(package, path).expect("enum not found"); + let path = registry + .resolve_rust_path(package, path) + .expect("enum not found"); quote! { #path } @@ -403,7 +425,8 @@ fn path_struct( }}); let ty = match ty { - ProtoType::Modified(ProtoModifiedValueType::Optional(value)) | ProtoType::Value(value) => Some(value), + ProtoType::Modified(ProtoModifiedValueType::Optional(value)) + | ProtoType::Value(value) => Some(value), _ => None, }; @@ -530,27 +553,35 @@ impl InputGenerator<'_> { let first_part = parts.next().expect("parts empty").to_owned(); // Start with the first part of the path - let mut current_map = self.used_paths.entry(first_part).or_insert(if parts.peek().is_none() { - ExcludePaths::True - } else { - ExcludePaths::Child(BTreeMap::new()) - }); + let mut current_map = + self.used_paths + .entry(first_part) + .or_insert(if parts.peek().is_none() { + ExcludePaths::True + } else { + ExcludePaths::Child(BTreeMap::new()) + }); // Iterate over the remaining parts of the path while let Some(part) = parts.next() { match current_map { ExcludePaths::True => anyhow::bail!("duplicate path: {field}"), ExcludePaths::Child(map) => { - current_map = map.entry(part.to_owned()).or_insert(if parts.peek().is_none() { - ExcludePaths::True - } else { - ExcludePaths::Child(BTreeMap::new()) - }); + current_map = map + .entry(part.to_owned()) + .or_insert(if parts.peek().is_none() { + ExcludePaths::True + } else { + ExcludePaths::Child(BTreeMap::new()) + }); } } } - anyhow::ensure!(matches!(current_map, ExcludePaths::True), "duplicate path: {field}"); + anyhow::ensure!( + matches!(current_map, ExcludePaths::True), + "duplicate path: {field}" + ); Ok(()) } @@ -561,7 +592,10 @@ impl InputGenerator<'_> { quote!((&mut #tracker, &mut #target)) } - pub(super) fn generate_query_parameter(&mut self, field: Option<&str>) -> anyhow::Result { + pub(super) fn generate_query_parameter( + &mut self, + field: Option<&str>, + ) -> anyhow::Result { let mut params = Vec::new(); let extract = if let Some(field) = field { @@ -581,7 +615,9 @@ impl InputGenerator<'_> { let exclude_paths = if let Some(field) = field { match self.used_paths.get(field) { Some(ExcludePaths::Child(c)) => Some(c), - Some(ExcludePaths::True) => anyhow::bail!("{field} is already used by another operation"), + Some(ExcludePaths::True) => { + anyhow::bail!("{field} is already used by another operation") + } None => None, } } else { @@ -601,11 +637,12 @@ impl InputGenerator<'_> { }; for (name, field) in &message_ty.fields { - let exclude_paths = match exclude_paths.and_then(|exclude_paths| exclude_paths.get(name)) { - Some(ExcludePaths::True) => continue, - Some(ExcludePaths::Child(child)) => Some(child), - None => None, - }; + let exclude_paths = + match exclude_paths.and_then(|exclude_paths| exclude_paths.get(name)) { + Some(ExcludePaths::True) => continue, + Some(ExcludePaths::Child(child)) => Some(child), + None => None, + }; params.push( openapiv3_1::path::Parameter::builder() .name(field.options.serde_name.clone()) @@ -648,7 +685,10 @@ impl InputGenerator<'_> { }) } - pub(super) fn generate_path_parameter(&mut self, path: &str) -> anyhow::Result { + pub(super) fn generate_path_parameter( + &mut self, + path: &str, + ) -> anyhow::Result { let params = parse_route(path); if params.is_empty() { return Ok(GeneratedParams::default()); @@ -658,7 +698,13 @@ impl InputGenerator<'_> { defs, mappings, param_schemas, - } = path_struct(self.types, &self.root_ty, self.package, ¶ms, self.base_extract())?; + } = path_struct( + self.types, + &self.root_ty, + self.package, + ¶ms, + self.base_extract(), + )?; let mut params = Vec::new(); for (path, (ty, cel)) in param_schemas { @@ -714,7 +760,12 @@ impl InputGenerator<'_> { ) -> anyhow::Result> { let content_type = if let Some(content_type_field) = content_type_field { self.consume_field(content_type_field)?; - let extract = input_field_getter_gen(self.types, &self.root_ty, self.base_extract(), content_type_field)?; + let extract = input_field_getter_gen( + self.types, + &self.root_ty, + self.base_extract(), + content_type_field, + )?; anyhow::ensure!( matches!(extract.ty.value_type(), Some(ProtoValueType::String)), @@ -750,7 +801,9 @@ impl InputGenerator<'_> { let exclude_paths = if let Some(field) = field { match self.used_paths.get(field) { Some(ExcludePaths::Child(c)) => Some(c), - Some(ExcludePaths::True) => anyhow::bail!("{field} is already used by another operation"), + Some(ExcludePaths::True) => { + anyhow::bail!("{field} is already used by another operation") + } None => None, } } else { @@ -840,7 +893,12 @@ impl OutputGenerator<'_> { let builder_ident = &self.builder_ident; let content_type = if let Some(content_type_field) = content_type_field { - let extract = output_field_getter_gen(self.types, &self.root_ty, self.base_extract(), content_type_field)?; + let extract = output_field_getter_gen( + self.types, + &self.root_ty, + self.base_extract(), + content_type_field, + )?; anyhow::ensure!( matches!(extract.ty.value_type(), Some(ProtoValueType::String)), @@ -849,7 +907,11 @@ impl OutputGenerator<'_> { anyhow::ensure!(!extract.ty.nested(), "content-type cannot be nested"); - let modifier = if extract.is_optional { quote!(Some(ct)) } else { quote!(ct) }; + let modifier = if extract.is_optional { + quote!(Some(ct)) + } else { + quote!(ct) + }; let extract = extract.tokens; let default_ct = body_method.default_content_type(); @@ -1009,19 +1071,26 @@ fn generate( let mut schemas = Vec::with_capacity(1 + cel.map_key.len()); for expr in &cel.map_key { - schemas.extend(handle_expr(compiler.child(), &ProtoType::Value(key.clone()), expr)?); + schemas.extend(handle_expr( + compiler.child(), + &ProtoType::Value(key.clone()), + expr, + )?); } - schemas.push(Schema::object(Object::builder().schema_type(Type::String))); + schemas + .push(Schema::object(Object::builder().schema_type(Type::String))); Object::all_ofs(schemas) } - ProtoValueType::Int32 | ProtoValueType::Int64 => { - Object::builder().schema_type(Type::String).pattern("^-?[0-9]+$").build() - } - ProtoValueType::UInt32 | ProtoValueType::UInt64 => { - Object::builder().schema_type(Type::String).pattern("^[0-9]+$").build() - } + ProtoValueType::Int32 | ProtoValueType::Int64 => Object::builder() + .schema_type(Type::String) + .pattern("^-?[0-9]+$") + .build(), + ProtoValueType::UInt32 | ProtoValueType::UInt64 => Object::builder() + .schema_type(Type::String) + .pattern("^[0-9]+$") + .build(), ProtoValueType::Bool => Object::builder() .schema_type(Type::String) .enum_values(["true", "false"]) @@ -1031,7 +1100,11 @@ fn generate( .additional_properties({ let mut schemas = Vec::with_capacity(1 + cel.map_value.len()); for expr in &cel.map_value { - schemas.extend(handle_expr(compiler.child(), &ProtoType::Value(value.clone()), expr)?); + schemas.extend(handle_expr( + compiler.child(), + &ProtoType::Value(value.clone()), + expr, + )?); } schemas.push(internal_generate( @@ -1106,7 +1179,9 @@ fn generate( Schema::object( Object::builder() .schema_type(Type::String) - .const_value(field.options.serde_name.clone()) + .const_value( + field.options.serde_name.clone(), + ) .build(), ), ); @@ -1178,7 +1253,9 @@ fn generate( ]) .build(), ), - ProtoType::Value(ProtoValueType::Bool) => Schema::object(Object::builder().schema_type(Type::Boolean).build()), + ProtoType::Value(ProtoValueType::Bool) => { + Schema::object(Object::builder().schema_type(Type::Boolean).build()) + } ProtoType::Value(ProtoValueType::Bytes) => Schema::object( Object::builder() .schema_type(Type::String) @@ -1215,39 +1292,50 @@ fn generate( ProtoType::Value(ProtoValueType::UInt32) => Schema::object(Object::uint32()), ProtoType::Value(ProtoValueType::Int64) => Schema::object(Object::int64()), ProtoType::Value(ProtoValueType::UInt64) => Schema::object(Object::uint64()), - ProtoType::Value(ProtoValueType::String) => Schema::object(Object::builder().schema_type(Type::String).build()), + ProtoType::Value(ProtoValueType::String) => { + Schema::object(Object::builder().schema_type(Type::String).build()) + } ProtoType::Value(ProtoValueType::Enum(enum_path)) => { let ety = types .get_enum(&enum_path) .with_context(|| format!("missing enum: {enum_path}"))?; - let schema_name = if ety - .variants - .values() - .any(|v| v.options.visibility.has_input() != v.options.visibility.has_output()) - { - format!("{direction:?}.{enum_path}") - } else { - enum_path.to_string() - }; + let schema_name = + if ety.variants.values().any(|v| { + v.options.visibility.has_input() != v.options.visibility.has_output() + }) { + format!("{direction:?}.{enum_path}") + } else { + enum_path.to_string() + }; if !components.schemas.contains_key(enum_path.as_ref()) { components.add_schema( schema_name.clone(), Schema::object( Object::builder() - .schema_type(if ety.options.repr_enum { Type::Integer } else { Type::String }) + .schema_type(if ety.options.repr_enum { + Type::Integer + } else { + Type::String + }) .enum_values( ety.variants .values() .filter(|v| match direction { - GenerateDirection::Input => v.options.visibility.has_input(), - GenerateDirection::Output => v.options.visibility.has_output(), + GenerateDirection::Input => { + v.options.visibility.has_input() + } + GenerateDirection::Output => { + v.options.visibility.has_output() + } }) .map(|v| { if ety.options.repr_enum { serde_json::Value::from(v.value) } else { - serde_json::Value::from(v.options.serde_name.clone()) + serde_json::Value::from( + v.options.serde_name.clone(), + ) } }) .collect::>(), @@ -1266,19 +1354,20 @@ fn generate( .get_message(message_path) .with_context(|| format!("missing message: {message_path}"))?; - let schema_name = if message_ty - .fields - .values() - .any(|v| v.options.visibility.has_input() != v.options.visibility.has_output()) - { - format!("{direction:?}.{message_path}") - } else { - message_path.to_string() - }; + let schema_name = + if message_ty.fields.values().any(|v| { + v.options.visibility.has_input() != v.options.visibility.has_output() + }) { + format!("{direction:?}.{message_path}") + } else { + message_path.to_string() + }; if !components.schemas.contains_key(&schema_name) || !used_paths.is_empty() { if used_paths.is_empty() { - components.schemas.insert(schema_name.clone(), Schema::Bool(false)); + components + .schemas + .insert(schema_name.clone(), Schema::Bool(false)); } let mut properties = IndexMap::new(); let mut required = Vec::new(); @@ -1288,10 +1377,15 @@ fn generate( schemas.extend(handle_expr(compiler.child(), ty, expr)?); } - for (name, field) in message_ty.fields.iter().filter(|(_, field)| match direction { - GenerateDirection::Input => field.options.visibility.has_input(), - GenerateDirection::Output => field.options.visibility.has_output(), - }) { + for (name, field) in + message_ty + .fields + .iter() + .filter(|(_, field)| match direction { + GenerateDirection::Input => field.options.visibility.has_input(), + GenerateDirection::Output => field.options.visibility.has_output(), + }) + { let exclude_paths = match used_paths.get(name) { Some(ExcludePaths::True) => continue, Some(ExcludePaths::Child(child)) => Some(child), @@ -1301,7 +1395,8 @@ fn generate( required.push(field.options.serde_name.clone()); } - let ty = match (!field.options.nullable || field.options.flatten, &field.ty) { + let ty = match (!field.options.nullable || field.options.flatten, &field.ty) + { (true, ProtoType::Modified(ProtoModifiedValueType::Optional(ty))) => { ProtoType::Value(ty.clone()) } @@ -1325,11 +1420,19 @@ fn generate( schemas.push(field_schema); } else { let schema = if field.options.nullable - && !matches!(&field.ty, ProtoType::Modified(ProtoModifiedValueType::Optional(_))) - { + && !matches!( + &field.ty, + ProtoType::Modified(ProtoModifiedValueType::Optional(_)) + ) { Schema::object( Object::builder() - .one_ofs([Object::builder().schema_type(Type::Null).build().into(), field_schema]) + .one_ofs([ + Object::builder() + .schema_type(Type::Null) + .build() + .into(), + field_schema, + ]) .build(), ) } else { @@ -1340,7 +1443,11 @@ fn generate( field.options.serde_name.clone(), Schema::object(Object::all_ofs([ schema, - Schema::object(Object::builder().description(field.comments.to_string()).build()), + Schema::object( + Object::builder() + .description(field.comments.to_string()) + .build(), + ), ])), ); } @@ -1358,7 +1465,10 @@ fn generate( )); if used_paths.is_empty() { - components.add_schema(schema_name.clone(), Object::all_ofs(schemas).into_optimized()); + components.add_schema( + schema_name.clone(), + Object::all_ofs(schemas).into_optimized(), + ); Schema::object(Ref::from_schema_name(schema_name)) } else { Schema::object(Object::all_ofs(schemas)) @@ -1368,32 +1478,46 @@ fn generate( } } ProtoType::Value(ProtoValueType::WellKnown(ProtoWellKnownType::Timestamp)) => { - Schema::object(Object::builder().schema_type(Type::String).format("date-time").build()) + Schema::object( + Object::builder() + .schema_type(Type::String) + .format("date-time") + .build(), + ) } ProtoType::Value(ProtoValueType::WellKnown(ProtoWellKnownType::Duration)) => { - Schema::object(Object::builder().schema_type(Type::String).format("duration").build()) + Schema::object( + Object::builder() + .schema_type(Type::String) + .format("duration") + .build(), + ) + } + ProtoType::Value(ProtoValueType::WellKnown(ProtoWellKnownType::Empty)) => { + Schema::object( + Object::builder() + .schema_type(Type::Object) + .unevaluated_properties(false) + .build(), + ) } - ProtoType::Value(ProtoValueType::WellKnown(ProtoWellKnownType::Empty)) => Schema::object( - Object::builder() - .schema_type(Type::Object) - .unevaluated_properties(false) - .build(), - ), ProtoType::Value(ProtoValueType::WellKnown(ProtoWellKnownType::ListValue)) => { Schema::object(Object::builder().schema_type(Type::Array).build()) } - ProtoType::Value(ProtoValueType::WellKnown(ProtoWellKnownType::Value)) => Schema::object( - Object::builder() - .schema_type(vec![ - Type::Null, - Type::Boolean, - Type::Object, - Type::Array, - Type::Number, - Type::String, - ]) - .build(), - ), + ProtoType::Value(ProtoValueType::WellKnown(ProtoWellKnownType::Value)) => { + Schema::object( + Object::builder() + .schema_type(vec![ + Type::Null, + Type::Boolean, + Type::Object, + Type::Array, + Type::Number, + Type::String, + ]) + .build(), + ) + } ProtoType::Value(ProtoValueType::WellKnown(ProtoWellKnownType::Struct)) => { Schema::object(Object::builder().schema_type(Type::Object).build()) } @@ -1408,5 +1532,6 @@ fn generate( Ok(Schema::object(Object::all_ofs(schemas))) } - internal_generate(field_info, components, types, used_paths, direction, bytes).map(|schema| schema.into_optimized()) + internal_generate(field_info, components, types, used_paths, direction, bytes) + .map(|schema| schema.into_optimized()) } diff --git a/tinc-build/src/codegen/utils.rs b/tinc-build/src/codegen/utils.rs index c2a9ddc..2e05bf8 100644 --- a/tinc-build/src/codegen/utils.rs +++ b/tinc-build/src/codegen/utils.rs @@ -14,9 +14,14 @@ pub(crate) fn get_common_import_path(package: &str, end: &str) -> syn::Path { let start_parts: Vec<&str> = package.split('.').collect(); let mut end_parts: Vec<&str> = end.split('.').collect(); - let end_part = type_ident_from_str(end_parts.pop().expect("end path must not be empty")).to_string(); + let end_part = + type_ident_from_str(end_parts.pop().expect("end path must not be empty")).to_string(); - let common_len = start_parts.iter().zip(&end_parts).take_while(|(a, b)| a == b).count(); + let common_len = start_parts + .iter() + .zip(&end_parts) + .take_while(|(a, b)| a == b) + .count(); let num_supers = start_parts.len().saturating_sub(common_len); @@ -45,19 +50,36 @@ mod tests { #[test] fn test_get_common_import_path() { assert_eq!( - get_common_import_path("a.b.c", "a.b.d").to_token_stream().to_string(), - syn::parse_str::("super::D").unwrap().to_token_stream().to_string() + get_common_import_path("a.b.c", "a.b.d") + .to_token_stream() + .to_string(), + syn::parse_str::("super::D") + .unwrap() + .to_token_stream() + .to_string() ); assert_eq!( - get_common_import_path("a.b.c", "a.b.c.d").to_token_stream().to_string(), - syn::parse_str::("D").unwrap().to_token_stream().to_string() + get_common_import_path("a.b.c", "a.b.c.d") + .to_token_stream() + .to_string(), + syn::parse_str::("D") + .unwrap() + .to_token_stream() + .to_string() ); assert_eq!( - get_common_import_path("a.b.c", "a.b.c").to_token_stream().to_string(), - syn::parse_str::("super::C").unwrap().to_token_stream().to_string() + get_common_import_path("a.b.c", "a.b.c") + .to_token_stream() + .to_string(), + syn::parse_str::("super::C") + .unwrap() + .to_token_stream() + .to_string() ); assert_eq!( - get_common_import_path("a.b.c", "a.b").to_token_stream().to_string(), + get_common_import_path("a.b.c", "a.b") + .to_token_stream() + .to_string(), syn::parse_str::("super::super::B") .unwrap() .to_token_stream() diff --git a/tinc-build/src/extern_paths.rs b/tinc-build/src/extern_paths.rs index a7a483e..39e7c21 100644 --- a/tinc-build/src/extern_paths.rs +++ b/tinc-build/src/extern_paths.rs @@ -30,8 +30,14 @@ impl ExternPaths { pub(crate) fn new(mode: Mode) -> Self { let mut paths = BTreeMap::new(); - paths.insert(ProtoPath::new("google.protobuf"), parse_quote!(::tinc::well_known::#mode)); - paths.insert(ProtoPath::new("tinc"), parse_quote!(::tinc::well_known::#mode::tinc)); + paths.insert( + ProtoPath::new("google.protobuf"), + parse_quote!(::tinc::well_known::#mode), + ); + paths.insert( + ProtoPath::new("tinc"), + parse_quote!(::tinc::well_known::#mode::tinc), + ); Self { paths } } @@ -44,7 +50,10 @@ impl ExternPaths { for (idx, _) in path.rmatch_indices('.') { if let Some(rust_path) = self.paths.get(&path[..idx]) { let mut segments = path[idx + 1..].split('.'); - let ident_type = segments.next_back().map(to_upper_camel).map(type_ident_from_str); + let ident_type = segments + .next_back() + .map(to_upper_camel) + .map(type_ident_from_str); let segments = segments.map(field_ident_from_str).chain(ident_type); return Some(parse_quote!( diff --git a/tinc-build/src/lib.rs b/tinc-build/src/lib.rs index 8277bb1..2f4e423 100644 --- a/tinc-build/src/lib.rs +++ b/tinc-build/src/lib.rs @@ -150,7 +150,11 @@ impl Config { } /// Compile and generate all the protos with the includes. - pub fn compile_protos(&mut self, protos: &[impl AsRef], includes: &[impl AsRef]) -> anyhow::Result<()> { + pub fn compile_protos( + &mut self, + protos: &[impl AsRef], + includes: &[impl AsRef], + ) -> anyhow::Result<()> { match self.mode { #[cfg(feature = "prost")] Mode::Prost => self.compile_protos_prost(protos, includes), @@ -166,7 +170,11 @@ impl Config { } #[cfg(feature = "prost")] - fn compile_protos_prost(&mut self, protos: &[impl AsRef], includes: &[impl AsRef]) -> anyhow::Result<()> { + fn compile_protos_prost( + &mut self, + protos: &[impl AsRef], + includes: &[impl AsRef], + ) -> anyhow::Result<()> { let fd_path = self.out_dir.join("tinc.fd.bin"); let mut config = prost_build::Config::new(); @@ -177,12 +185,17 @@ impl Config { { let tinc_out = self.out_dir.join("tinc"); std::fs::create_dir_all(&tinc_out).context("failed to create tinc directory")?; - std::fs::write(tinc_out.join("annotations.proto"), tinc_pb_prost::TINC_ANNOTATIONS) - .context("failed to write tinc_annotations.rs")?; + std::fs::write( + tinc_out.join("annotations.proto"), + tinc_pb_prost::TINC_ANNOTATIONS, + ) + .context("failed to write tinc_annotations.rs")?; includes.push(&self.out_dir); } - config.load_fds(protos, &includes).context("failed to generate tonic fds")?; + config + .load_fds(protos, &includes) + .context("failed to generate tonic fds")?; let fds_bytes = std::fs::read(fd_path).context("failed to read tonic fds")?; self.load_fds_prost(fds_bytes.as_slice()) } @@ -252,78 +265,102 @@ impl Config { }); enum_config.variants().for_each(|variant| { let path = format!("{path}.{variant}"); - enum_config.variant_attributes(variant).for_each(|attribute| { - config.field_attribute(&path, attribute.to_token_stream().to_string()); - }); + enum_config + .variant_attributes(variant) + .for_each(|attribute| { + config.field_attribute(&path, attribute.to_token_stream().to_string()); + }); }); }); - package.message_configs().for_each(|(path, message_config)| { - if self.extern_paths.contains(path) { - return; - } + package + .message_configs() + .for_each(|(path, message_config)| { + if self.extern_paths.contains(path) { + return; + } - message_config.attributes().for_each(|attribute| { - config.message_attribute(path, attribute.to_token_stream().to_string()); - }); - message_config.fields().for_each(|field| { - let path = format!("{path}.{field}"); - message_config.field_attributes(field).for_each(|attribute| { - config.field_attribute(&path, attribute.to_token_stream().to_string()); - }); - }); - message_config.oneof_configs().for_each(|(field, oneof_config)| { - let path = format!("{path}.{field}"); - oneof_config.attributes().for_each(|attribute| { - // In prost oneofs (container) are treated as enums - config.enum_attribute(&path, attribute.to_token_stream().to_string()); + message_config.attributes().for_each(|attribute| { + config.message_attribute(path, attribute.to_token_stream().to_string()); }); - oneof_config.fields().for_each(|field| { + message_config.fields().for_each(|field| { let path = format!("{path}.{field}"); - oneof_config.field_attributes(field).for_each(|attribute| { - config.field_attribute(&path, attribute.to_token_stream().to_string()); - }); + message_config + .field_attributes(field) + .for_each(|attribute| { + config.field_attribute( + &path, + attribute.to_token_stream().to_string(), + ); + }); }); + message_config + .oneof_configs() + .for_each(|(field, oneof_config)| { + let path = format!("{path}.{field}"); + oneof_config.attributes().for_each(|attribute| { + // In prost oneofs (container) are treated as enums + config + .enum_attribute(&path, attribute.to_token_stream().to_string()); + }); + oneof_config.fields().for_each(|field| { + let path = format!("{path}.{field}"); + oneof_config.field_attributes(field).for_each(|attribute| { + config.field_attribute( + &path, + attribute.to_token_stream().to_string(), + ); + }); + }); + }); }); - }); - package.extra_items.extend(package.services.iter().flat_map(|service| { - let mut builder = tonic_build::CodeGenBuilder::new(); + package + .extra_items + .extend(package.services.iter().flat_map(|service| { + let mut builder = tonic_build::CodeGenBuilder::new(); - builder.emit_package(true).build_transport(true); + builder.emit_package(true).build_transport(true); - let make_service = |is_client: bool| { - let mut builder = tonic_build::manual::Service::builder() - .name(service.name()) - .package(&service.package); + let make_service = |is_client: bool| { + let mut builder = tonic_build::manual::Service::builder() + .name(service.name()) + .package(&service.package); - if !service.comments.is_empty() { - builder = builder.comment(service.comments.to_string()); - } + if !service.comments.is_empty() { + builder = builder.comment(service.comments.to_string()); + } - service + service .methods .iter() .fold(builder, |service_builder, (name, method)| { - let codec_path = - if let Some(Some(codec_path)) = (!is_client).then_some(method.codec_path.as_ref()) { - let path = get_common_import_path(&service.full_name, codec_path); - quote!(#path::<::tinc::reexports::tonic_prost::ProstCodec<_, _>>) - } else { - quote!(::tinc::reexports::tonic_prost::ProstCodec) - }; + let codec_path = if let Some(Some(codec_path)) = + (!is_client).then_some(method.codec_path.as_ref()) + { + let path = get_common_import_path(&service.full_name, codec_path); + quote!(#path::<::tinc::reexports::tonic_prost::ProstCodec<_, _>>) + } else { + quote!(::tinc::reexports::tonic_prost::ProstCodec) + }; let mut builder = tonic_build::manual::Method::builder() .input_type( registry - .resolve_rust_path(&service.full_name, method.input.value_type().proto_path()) + .resolve_rust_path( + &service.full_name, + method.input.value_type().proto_path(), + ) .unwrap() .to_token_stream() .to_string(), ) .output_type( registry - .resolve_rust_path(&service.full_name, method.output.value_type().proto_path()) + .resolve_rust_path( + &service.full_name, + method.output.value_type().proto_path(), + ) .unwrap() .to_token_stream() .to_string(), @@ -347,31 +384,35 @@ impl Config { service_builder.method(builder.build()) }) .build() - }; - - let mut client: syn::ItemMod = syn::parse2(builder.generate_client(&make_service(true), "")).unwrap(); - client.content.as_mut().unwrap().1.insert( - 0, - parse_quote!( - use ::tinc::reexports::tonic; - ), - ); - - let mut server: syn::ItemMod = syn::parse2(builder.generate_server(&make_service(false), "")).unwrap(); - server.content.as_mut().unwrap().1.insert( - 0, - parse_quote!( - use ::tinc::reexports::tonic; - ), - ); - - [client.into(), server.into()] - })); + }; + + let mut client: syn::ItemMod = + syn::parse2(builder.generate_client(&make_service(true), "")).unwrap(); + client.content.as_mut().unwrap().1.insert( + 0, + parse_quote!( + use ::tinc::reexports::tonic; + ), + ); + + let mut server: syn::ItemMod = + syn::parse2(builder.generate_server(&make_service(false), "")).unwrap(); + server.content.as_mut().unwrap().1.insert( + 0, + parse_quote!( + use ::tinc::reexports::tonic; + ), + ); + + [client.into(), server.into()] + })); }); for package in packages.keys() { match std::fs::remove_file(self.out_dir.join(format!("{package}.rs"))) { - Err(err) if err.kind() != ErrorKind::NotFound => return Err(anyhow::anyhow!(err).context("remove")), + Err(err) if err.kind() != ErrorKind::NotFound => { + return Err(anyhow::anyhow!(err).context("remove")); + } _ => {} } } @@ -391,7 +432,8 @@ impl Config { }; let path = self.out_dir.join(format!("{package}.rs")); - write_module(&path, std::mem::take(&mut module.extra_items)).with_context(|| package.to_owned())?; + write_module(&path, std::mem::take(&mut module.extra_items)) + .with_context(|| package.to_owned())?; } #[derive(Default)] @@ -434,8 +476,11 @@ impl Config { } let file: syn::File = parse_quote!(#module); - std::fs::write(self.out_dir.join("___root_module.rs"), prettyplease::unparse(&file)) - .context("write root module")?; + std::fs::write( + self.out_dir.join("___root_module.rs"), + prettyplease::unparse(&file), + ) + .context("write root module")?; } Ok(()) @@ -445,7 +490,9 @@ impl Config { fn write_module(path: &std::path::Path, module: Vec) -> anyhow::Result<()> { let mut file = match std::fs::read_to_string(path) { Ok(content) if !content.is_empty() => syn::parse_file(&content).context("parse")?, - Err(err) if err.kind() != ErrorKind::NotFound => return Err(anyhow::anyhow!(err).context("read")), + Err(err) if err.kind() != ErrorKind::NotFound => { + return Err(anyhow::anyhow!(err).context("read")); + } _ => syn::File { attrs: Vec::new(), items: Vec::new(), diff --git a/tinc-build/src/prost_explore.rs b/tinc-build/src/prost_explore.rs index d9c8022..462b4ff 100644 --- a/tinc-build/src/prost_explore.rs +++ b/tinc-build/src/prost_explore.rs @@ -5,7 +5,8 @@ use convert_case::{Case, Casing}; use indexmap::IndexMap; use prost_reflect::prost_types::source_code_info::Location; use prost_reflect::{ - DescriptorPool, EnumDescriptor, ExtensionDescriptor, FileDescriptor, Kind, MessageDescriptor, ServiceDescriptor, + DescriptorPool, EnumDescriptor, ExtensionDescriptor, FileDescriptor, Kind, MessageDescriptor, + ServiceDescriptor, }; use quote::format_ident; use tinc_cel::{CelEnum, CelValueConv}; @@ -13,11 +14,11 @@ use tinc_cel::{CelEnum, CelValueConv}; use crate::codegen::cel::{CelExpression, CelExpressions}; use crate::codegen::prost_sanatize::{strip_enum_prefix, to_upper_camel}; use crate::types::{ - Comments, ProtoEnumOptions, ProtoEnumType, ProtoEnumVariant, ProtoEnumVariantOptions, ProtoFieldOptions, - ProtoFieldSerdeOmittable, ProtoMessageField, ProtoMessageOptions, ProtoMessageType, ProtoModifiedValueType, - ProtoOneOfField, ProtoOneOfOptions, ProtoOneOfType, ProtoPath, ProtoService, ProtoServiceMethod, - ProtoServiceMethodEndpoint, ProtoServiceMethodIo, ProtoServiceOptions, ProtoType, ProtoTypeRegistry, ProtoValueType, - ProtoVisibility, Tagged, + Comments, ProtoEnumOptions, ProtoEnumType, ProtoEnumVariant, ProtoEnumVariantOptions, + ProtoFieldOptions, ProtoFieldSerdeOmittable, ProtoMessageField, ProtoMessageOptions, + ProtoMessageType, ProtoModifiedValueType, ProtoOneOfField, ProtoOneOfOptions, ProtoOneOfType, + ProtoPath, ProtoService, ProtoServiceMethod, ProtoServiceMethodEndpoint, ProtoServiceMethodIo, + ProtoServiceOptions, ProtoType, ProtoTypeRegistry, ProtoValueType, ProtoVisibility, Tagged, }; pub(crate) struct Extension { @@ -69,9 +70,13 @@ impl Extension { match message.as_ref() { prost_reflect::Value::Message(message) => { if message.fields().next().is_some() { - let message = message - .transcode_to::() - .with_context(|| format!("{} is not a valid {}", self.name, std::any::type_name::()))?; + let message = message.transcode_to::().with_context(|| { + format!( + "{} is not a valid {}", + self.name, + std::any::type_name::() + ) + })?; Ok(vec![message]) } else { Ok(Vec::new()) @@ -279,14 +284,22 @@ impl<'a> FileWalker<'a> { Ok(()) } - fn process_service(&self, service: &ServiceDescriptor, registry: &mut ProtoTypeRegistry) -> anyhow::Result<()> { + fn process_service( + &self, + service: &ServiceDescriptor, + registry: &mut ProtoTypeRegistry, + ) -> anyhow::Result<()> { if registry.get_service(service.full_name()).is_some() { return Ok(()); } let mut methods = IndexMap::new(); - let opts = self.extensions.ext_service.decode(service)?.unwrap_or_default(); + let opts = self + .extensions + .ext_service + .decode(service)? + .unwrap_or_default(); let service_full_name = ProtoPath::new(service.full_name()); for method in service.methods() { @@ -321,7 +334,10 @@ impl<'a> FileWalker<'a> { ProtoServiceMethod { full_name: ProtoPath::new(method.full_name()), service: service_full_name.clone(), - comments: self.location(method.path()).map(location_to_comments).unwrap_or_default(), + comments: self + .location(method.path()) + .map(location_to_comments) + .unwrap_or_default(), input: if method.is_client_streaming() { ProtoServiceMethodIo::Stream(method_input) } else { @@ -349,16 +365,25 @@ impl<'a> FileWalker<'a> { registry.register_service(ProtoService { full_name: ProtoPath::new(service.full_name()), - comments: self.location(service.path()).map(location_to_comments).unwrap_or_default(), + comments: self + .location(service.path()) + .map(location_to_comments) + .unwrap_or_default(), package: ProtoPath::new(service.package_name()), - options: ProtoServiceOptions { prefix: opts.prefix }, + options: ProtoServiceOptions { + prefix: opts.prefix, + }, methods, }); Ok(()) } - fn process_message(&self, message: &MessageDescriptor, registry: &mut ProtoTypeRegistry) -> anyhow::Result<()> { + fn process_message( + &self, + message: &MessageDescriptor, + registry: &mut ProtoTypeRegistry, + ) -> anyhow::Result<()> { let opts = self.extensions.ext_message.decode(message)?; let fields = message @@ -375,11 +400,16 @@ impl<'a> FileWalker<'a> { let opts = opts.unwrap_or_default(); let message_full_name = ProtoPath::new(message.full_name()); - let rename_all = opts.rename_all.and_then(|v| tinc_pb_prost::RenameAll::try_from(v).ok()); + let rename_all = opts + .rename_all + .and_then(|v| tinc_pb_prost::RenameAll::try_from(v).ok()); let mut message_type = ProtoMessageType { full_name: message_full_name.clone(), - comments: self.location(message.path()).map(location_to_comments).unwrap_or_default(), + comments: self + .location(message.path()) + .map(location_to_comments) + .unwrap_or_default(), package: ProtoPath::new(message.package_name()), fields: IndexMap::new(), options: ProtoMessageOptions { @@ -402,7 +432,10 @@ impl<'a> FileWalker<'a> { let visibility = ProtoVisibility::from_pb(opts.visibility()); let field_opts = ProtoFieldOptions { - serde_omittable: ProtoFieldSerdeOmittable::from_prost_pb(opts.json_omittable(), proto3_optional), + serde_omittable: ProtoFieldSerdeOmittable::from_prost_pb( + opts.json_omittable(), + proto3_optional, + ), nullable: proto3_optional, visibility, flatten: opts.flatten(), @@ -410,8 +443,11 @@ impl<'a> FileWalker<'a> { .rename .or_else(|| rename_field(field.name(), rename_all?)) .unwrap_or_else(|| field.name().to_owned()), - cel_exprs: gather_cel_expressions(&self.extensions.ext_predefined, &field.options()) - .context("gathering cel expressions")?, + cel_exprs: gather_cel_expressions( + &self.extensions.ext_predefined, + &field.options(), + ) + .context("gathering cel expressions")?, }; let Some(Some(oneof)) = (!proto3_optional).then(|| field.containing_oneof()) else { @@ -420,18 +456,27 @@ impl<'a> FileWalker<'a> { ProtoMessageField { full_name: ProtoPath::new(field.full_name()), message: message_full_name.clone(), - comments: self.location(field.path()).map(location_to_comments).unwrap_or_default(), + comments: self + .location(field.path()) + .map(location_to_comments) + .unwrap_or_default(), ty: match field.kind() { - Kind::Message(message) if field.is_map() => ProtoType::Modified(ProtoModifiedValueType::Map( - ProtoValueType::from_pb(&message.map_entry_key_field().kind()), - ProtoValueType::from_pb(&message.map_entry_value_field().kind()), - )), - // Prost will generate messages as optional even if they are not optional in the proto. - kind if field.is_list() => { - ProtoType::Modified(ProtoModifiedValueType::Repeated(ProtoValueType::from_pb(&kind))) + Kind::Message(message) if field.is_map() => { + ProtoType::Modified(ProtoModifiedValueType::Map( + ProtoValueType::from_pb(&message.map_entry_key_field().kind()), + ProtoValueType::from_pb( + &message.map_entry_value_field().kind(), + ), + )) } + // Prost will generate messages as optional even if they are not optional in the proto. + kind if field.is_list() => ProtoType::Modified( + ProtoModifiedValueType::Repeated(ProtoValueType::from_pb(&kind)), + ), kind if proto3_optional || matches!(kind, Kind::Message(_)) => { - ProtoType::Modified(ProtoModifiedValueType::Optional(ProtoValueType::from_pb(&kind))) + ProtoType::Modified(ProtoModifiedValueType::Optional( + ProtoValueType::from_pb(&kind), + )) } kind => ProtoType::Value(ProtoValueType::from_pb(&kind)), }, @@ -441,18 +486,26 @@ impl<'a> FileWalker<'a> { continue; }; - let opts = self.extensions.ext_oneof.decode(&oneof)?.unwrap_or_default(); + let opts = self + .extensions + .ext_oneof + .decode(&oneof)? + .unwrap_or_default(); let mut entry = message_type.fields.entry(oneof.name().to_owned()); let oneof = match entry { indexmap::map::Entry::Occupied(ref mut entry) => entry.get_mut(), indexmap::map::Entry::Vacant(entry) => { let visibility = ProtoVisibility::from_pb(opts.visibility()); - let json_omittable = ProtoFieldSerdeOmittable::from_prost_pb(opts.json_omittable(), false); + let json_omittable = + ProtoFieldSerdeOmittable::from_prost_pb(opts.json_omittable(), false); entry.insert(ProtoMessageField { full_name: ProtoPath::new(oneof.full_name()), message: message_full_name.clone(), - comments: self.location(oneof.path()).map(location_to_comments).unwrap_or_default(), + comments: self + .location(oneof.path()) + .map(location_to_comments) + .unwrap_or_default(), options: ProtoFieldOptions { flatten: opts.flatten(), nullable: json_omittable.is_true(), @@ -498,7 +551,10 @@ impl<'a> FileWalker<'a> { // instead of through the oneof. full_name: ProtoPath::new(format!("{full_name}.{}", field.name())), message: message_full_name.clone(), - comments: self.location(field.path()).map(location_to_comments).unwrap_or_default(), + comments: self + .location(field.path()) + .map(location_to_comments) + .unwrap_or_default(), ty: field_ty.clone(), options: field_opts, }, @@ -522,7 +578,11 @@ impl<'a> FileWalker<'a> { Ok(()) } - fn process_enum(&self, enum_: &EnumDescriptor, registry: &mut ProtoTypeRegistry) -> anyhow::Result<()> { + fn process_enum( + &self, + enum_: &EnumDescriptor, + registry: &mut ProtoTypeRegistry, + ) -> anyhow::Result<()> { let opts = self.extensions.ext_enum.decode(enum_)?; let values = enum_ @@ -545,7 +605,10 @@ impl<'a> FileWalker<'a> { let mut enum_opts = ProtoEnumType { full_name: ProtoPath::new(enum_.full_name()), - comments: self.location(enum_.path()).map(location_to_comments).unwrap_or_default(), + comments: self + .location(enum_.path()) + .map(location_to_comments) + .unwrap_or_default(), package: ProtoPath::new(enum_.package_name()), variants: IndexMap::new(), options: ProtoEnumOptions { @@ -558,19 +621,28 @@ impl<'a> FileWalker<'a> { let visibility = ProtoVisibility::from_pb(opts.visibility()); - let name = strip_enum_prefix(&to_upper_camel(enum_.name()), &to_upper_camel(variant.name())); + let name = strip_enum_prefix( + &to_upper_camel(enum_.name()), + &to_upper_camel(variant.name()), + ); enum_opts.variants.insert( variant.name().to_owned(), ProtoEnumVariant { - comments: self.location(variant.path()).map(location_to_comments).unwrap_or_default(), + comments: self + .location(variant.path()) + .map(location_to_comments) + .unwrap_or_default(), // This is not the same as variant.full_name() because that strips the enum name. full_name: ProtoPath::new(format!("{}.{}", enum_.full_name(), variant.name())), value: variant.number(), rust_ident: format_ident!("{name}"), options: ProtoEnumVariantOptions { visibility, - serde_name: opts.rename.or_else(|| rename_field(&name, rename_all)).unwrap_or(name), + serde_name: opts + .rename + .or_else(|| rename_field(&name, rename_all)) + .unwrap_or(name), }, }, ); @@ -664,7 +736,9 @@ fn explore_fields( results.entry(input).or_default().extend( list.iter() .filter_map(|item| item.as_message()) - .filter_map(|msg| msg.transcode_to::().ok()) + .filter_map(|msg| { + msg.transcode_to::().ok() + }) .map(|expr| CelExpression { expression: expr.expression, jsonschemas: expr.jsonschemas, @@ -744,10 +818,19 @@ fn prost_to_cel(value: &prost_reflect::Value, kind: &Kind) -> tinc_cel::CelValue prost_reflect::MapKey::I64(v) => v.conv(), prost_reflect::MapKey::U32(v) => v.conv(), prost_reflect::MapKey::U64(v) => v.conv(), - prost_reflect::MapKey::String(s) => tinc_cel::CelValue::String(s.clone().into()), + prost_reflect::MapKey::String(s) => { + tinc_cel::CelValue::String(s.clone().into()) + } }; - let v = prost_to_cel(value, &kind.as_message().expect("map").map_entry_value_field().kind()); + let v = prost_to_cel( + value, + &kind + .as_message() + .expect("map") + .map_entry_value_field() + .kind(), + ); (key, v) }) .collect(), @@ -758,7 +841,11 @@ fn prost_to_cel(value: &prost_reflect::Value, kind: &Kind) -> tinc_cel::CelValue fn location_to_comments(location: &Location) -> Comments { Comments { leading: location.leading_comments.as_deref().map(Into::into), - detached: location.leading_detached_comments.iter().map(|s| s.as_str().into()).collect(), + detached: location + .leading_detached_comments + .iter() + .map(|s| s.as_str().into()) + .collect(), trailing: location.trailing_comments.as_deref().map(Into::into), } } diff --git a/tinc-build/src/types.rs b/tinc-build/src/types.rs index fb960bc..7726be7 100644 --- a/tinc-build/src/types.rs +++ b/tinc-build/src/types.rs @@ -78,8 +78,12 @@ impl ProtoValueType { prost_reflect::Kind::Bool => ProtoValueType::Bool, prost_reflect::Kind::String => ProtoValueType::String, prost_reflect::Kind::Bytes => ProtoValueType::Bytes, - prost_reflect::Kind::Message(message) => ProtoValueType::from_proto_path(message.full_name()), - prost_reflect::Kind::Enum(enum_) => ProtoValueType::Enum(ProtoPath::new(enum_.full_name())), + prost_reflect::Kind::Message(message) => { + ProtoValueType::from_proto_path(message.full_name()) + } + prost_reflect::Kind::Enum(enum_) => { + ProtoValueType::Enum(ProtoPath::new(enum_.full_name())) + } } } @@ -464,7 +468,11 @@ pub(crate) struct ProtoTypeRegistry { } impl ProtoTypeRegistry { - pub(crate) fn new(mode: Mode, extern_paths: ExternPaths, floats_with_non_finite_vals: PathSet) -> Self { + pub(crate) fn new( + mode: Mode, + extern_paths: ExternPaths, + floats_with_non_finite_vals: PathSet, + ) -> Self { Self { messages: BTreeMap::new(), enums: BTreeMap::new(), diff --git a/tinc-cel/src/lib.rs b/tinc-cel/src/lib.rs index 7b809a5..99cb4e1 100644 --- a/tinc-cel/src/lib.rs +++ b/tinc-cel/src/lib.rs @@ -44,9 +44,7 @@ pub enum CelError<'a> { value: CelValue<'a>, }, #[error("number out of range when performing {op}")] - NumberOutOfRange { - op: &'static str, - }, + NumberOutOfRange { op: &'static str }, #[error("bad access when trying to member {member} on {container}")] BadAccess { member: CelValue<'a>, @@ -186,7 +184,10 @@ impl PartialOrd for CelValue<'_> { fn partial_cmp(&self, other: &Self) -> Option { match (self, other) { (CelValue::Number(l), CelValue::Number(r)) => l.partial_cmp(r), - (CelValue::String(_) | CelValue::Bytes(_), CelValue::String(_) | CelValue::Bytes(_)) => { + ( + CelValue::String(_) | CelValue::Bytes(_), + CelValue::String(_) | CelValue::Bytes(_), + ) => { let l = match self { CelValue::String(s) => s.as_ref().as_bytes(), CelValue::Bytes(b) => b.as_ref(), @@ -207,7 +208,10 @@ impl PartialOrd for CelValue<'_> { } impl<'a> CelValue<'a> { - pub fn cel_access<'b>(container: impl CelValueConv<'a>, key: impl CelValueConv<'b>) -> Result, CelError<'b>> + pub fn cel_access<'b>( + container: impl CelValueConv<'a>, + key: impl CelValueConv<'b>, + ) -> Result, CelError<'b>> where 'a: 'b, { @@ -220,7 +224,9 @@ impl<'a> CelValue<'a> { .ok_or(CelError::MapKeyNotFound(key)), CelValue::List(list) => { if let Some(idx) = key.as_number().and_then(|n| n.to_usize()) { - list.get(idx).cloned().ok_or(CelError::IndexOutOfBounds(idx, list.len())) + list.get(idx) + .cloned() + .ok_or(CelError::IndexOutOfBounds(idx, list.len())) } else { Err(CelError::IndexWithBadIndex(key)) } @@ -232,50 +238,87 @@ impl<'a> CelValue<'a> { } } - pub fn cel_add(left: impl CelValueConv<'a>, right: impl CelValueConv<'a>) -> Result, CelError<'a>> { + pub fn cel_add( + left: impl CelValueConv<'a>, + right: impl CelValueConv<'a>, + ) -> Result, CelError<'a>> { match (left.conv(), right.conv()) { (CelValue::Number(l), CelValue::Number(r)) => Ok(CelValue::Number(l.cel_add(r)?)), - (CelValue::String(l), CelValue::String(r)) => Ok(CelValue::String(CelString::Owned(Arc::from(format!( - "{}{}", - l.as_ref(), - r.as_ref() - ))))), + (CelValue::String(l), CelValue::String(r)) => Ok(CelValue::String(CelString::Owned( + Arc::from(format!("{}{}", l.as_ref(), r.as_ref())), + ))), (CelValue::Bytes(l), CelValue::Bytes(r)) => Ok(CelValue::Bytes(CelBytes::Owned({ let mut l = l.as_ref().to_vec(); l.extend_from_slice(r.as_ref()); Bytes::from(l) }))), - (CelValue::List(l), CelValue::List(r)) => Ok(CelValue::List(l.iter().chain(r.iter()).cloned().collect())), - (CelValue::Map(l), CelValue::Map(r)) => Ok(CelValue::Map(l.iter().chain(r.iter()).cloned().collect())), - (left, right) => Err(CelError::BadOperation { left, right, op: "+" }), + (CelValue::List(l), CelValue::List(r)) => { + Ok(CelValue::List(l.iter().chain(r.iter()).cloned().collect())) + } + (CelValue::Map(l), CelValue::Map(r)) => { + Ok(CelValue::Map(l.iter().chain(r.iter()).cloned().collect())) + } + (left, right) => Err(CelError::BadOperation { + left, + right, + op: "+", + }), } } - pub fn cel_sub(left: impl CelValueConv<'a>, right: impl CelValueConv<'a>) -> Result, CelError<'a>> { + pub fn cel_sub( + left: impl CelValueConv<'a>, + right: impl CelValueConv<'a>, + ) -> Result, CelError<'a>> { match (left.conv(), right.conv()) { (CelValue::Number(l), CelValue::Number(r)) => Ok(CelValue::Number(l.cel_sub(r)?)), - (left, right) => Err(CelError::BadOperation { left, right, op: "-" }), + (left, right) => Err(CelError::BadOperation { + left, + right, + op: "-", + }), } } - pub fn cel_mul(left: impl CelValueConv<'a>, right: impl CelValueConv<'a>) -> Result, CelError<'a>> { + pub fn cel_mul( + left: impl CelValueConv<'a>, + right: impl CelValueConv<'a>, + ) -> Result, CelError<'a>> { match (left.conv(), right.conv()) { (CelValue::Number(l), CelValue::Number(r)) => Ok(CelValue::Number(l.cel_mul(r)?)), - (left, right) => Err(CelError::BadOperation { left, right, op: "*" }), + (left, right) => Err(CelError::BadOperation { + left, + right, + op: "*", + }), } } - pub fn cel_div(left: impl CelValueConv<'a>, right: impl CelValueConv<'a>) -> Result, CelError<'a>> { + pub fn cel_div( + left: impl CelValueConv<'a>, + right: impl CelValueConv<'a>, + ) -> Result, CelError<'a>> { match (left.conv(), right.conv()) { (CelValue::Number(l), CelValue::Number(r)) => Ok(CelValue::Number(l.cel_div(r)?)), - (left, right) => Err(CelError::BadOperation { left, right, op: "/" }), + (left, right) => Err(CelError::BadOperation { + left, + right, + op: "/", + }), } } - pub fn cel_rem(left: impl CelValueConv<'a>, right: impl CelValueConv<'a>) -> Result, CelError<'a>> { + pub fn cel_rem( + left: impl CelValueConv<'a>, + right: impl CelValueConv<'a>, + ) -> Result, CelError<'a>> { match (left.conv(), right.conv()) { (CelValue::Number(l), CelValue::Number(r)) => Ok(CelValue::Number(l.cel_rem(r)?)), - (left, right) => Err(CelError::BadOperation { left, right, op: "%" }), + (left, right) => Err(CelError::BadOperation { + left, + right, + op: "%", + }), } } @@ -295,59 +338,100 @@ impl<'a> CelValue<'a> { } // left < right - pub fn cel_lt(left: impl CelValueConv<'a>, right: impl CelValueConv<'a>) -> Result> { + pub fn cel_lt( + left: impl CelValueConv<'a>, + right: impl CelValueConv<'a>, + ) -> Result> { let left = left.conv(); let right = right.conv(); left.partial_cmp(&right) - .ok_or(CelError::BadOperation { left, right, op: "<" }) + .ok_or(CelError::BadOperation { + left, + right, + op: "<", + }) .map(|o| matches!(o, std::cmp::Ordering::Less)) } // left <= right - pub fn cel_lte(left: impl CelValueConv<'a>, right: impl CelValueConv<'a>) -> Result> { + pub fn cel_lte( + left: impl CelValueConv<'a>, + right: impl CelValueConv<'a>, + ) -> Result> { let left = left.conv(); let right = right.conv(); left.partial_cmp(&right) - .ok_or(CelError::BadOperation { left, right, op: "<=" }) + .ok_or(CelError::BadOperation { + left, + right, + op: "<=", + }) .map(|o| matches!(o, std::cmp::Ordering::Less | std::cmp::Ordering::Equal)) } // left > right - pub fn cel_gt(left: impl CelValueConv<'a>, right: impl CelValueConv<'a>) -> Result> { + pub fn cel_gt( + left: impl CelValueConv<'a>, + right: impl CelValueConv<'a>, + ) -> Result> { let left = left.conv(); let right = right.conv(); left.partial_cmp(&right) - .ok_or(CelError::BadOperation { left, right, op: ">" }) + .ok_or(CelError::BadOperation { + left, + right, + op: ">", + }) .map(|o| matches!(o, std::cmp::Ordering::Greater)) } // left >= right - pub fn cel_gte(left: impl CelValueConv<'a>, right: impl CelValueConv<'a>) -> Result> { + pub fn cel_gte( + left: impl CelValueConv<'a>, + right: impl CelValueConv<'a>, + ) -> Result> { let left = left.conv(); let right = right.conv(); left.partial_cmp(&right) - .ok_or(CelError::BadOperation { left, right, op: ">=" }) + .ok_or(CelError::BadOperation { + left, + right, + op: ">=", + }) .map(|o| matches!(o, std::cmp::Ordering::Greater | std::cmp::Ordering::Equal)) } // left == right - pub fn cel_eq(left: impl CelValueConv<'a>, right: impl CelValueConv<'a>) -> Result> { + pub fn cel_eq( + left: impl CelValueConv<'a>, + right: impl CelValueConv<'a>, + ) -> Result> { let left = left.conv(); let right = right.conv(); Ok(left == right) } // left != right - pub fn cel_neq(left: impl CelValueConv<'a>, right: impl CelValueConv<'a>) -> Result> { + pub fn cel_neq( + left: impl CelValueConv<'a>, + right: impl CelValueConv<'a>, + ) -> Result> { let left = left.conv(); let right = right.conv(); Ok(left != right) } // left.contains(right) - pub fn cel_contains(left: impl CelValueConv<'a>, right: impl CelValueConv<'a>) -> Result> { + pub fn cel_contains( + left: impl CelValueConv<'a>, + right: impl CelValueConv<'a>, + ) -> Result> { Self::cel_in(right, left).map_err(|err| match err { - CelError::BadOperation { left, right, op: "in" } => CelError::BadOperation { + CelError::BadOperation { + left, + right, + op: "in", + } => CelError::BadOperation { left: right, right: left, op: "contains", @@ -358,11 +442,17 @@ impl<'a> CelValue<'a> { } // left in right - pub fn cel_in(left: impl CelValueConv<'a>, right: impl CelValueConv<'a>) -> Result> { + pub fn cel_in( + left: impl CelValueConv<'a>, + right: impl CelValueConv<'a>, + ) -> Result> { match (left.conv(), right.conv()) { (left, CelValue::List(r)) => Ok(r.contains(&left)), (left, CelValue::Map(r)) => Ok(r.iter().any(|(k, _)| k == &left)), - (left @ (CelValue::Bytes(_) | CelValue::String(_)), right @ (CelValue::Bytes(_) | CelValue::String(_))) => { + ( + left @ (CelValue::Bytes(_) | CelValue::String(_)), + right @ (CelValue::Bytes(_) | CelValue::String(_)), + ) => { let r = match &right { CelValue::Bytes(b) => b.as_ref(), CelValue::String(s) => s.as_ref().as_bytes(), @@ -377,13 +467,23 @@ impl<'a> CelValue<'a> { Ok(r.windows(l.len()).any(|w| w == l)) } - (left, right) => Err(CelError::BadOperation { left, right, op: "in" }), + (left, right) => Err(CelError::BadOperation { + left, + right, + op: "in", + }), } } - pub fn cel_starts_with(left: impl CelValueConv<'a>, right: impl CelValueConv<'a>) -> Result> { + pub fn cel_starts_with( + left: impl CelValueConv<'a>, + right: impl CelValueConv<'a>, + ) -> Result> { match (left.conv(), right.conv()) { - (left @ (CelValue::Bytes(_) | CelValue::String(_)), right @ (CelValue::Bytes(_) | CelValue::String(_))) => { + ( + left @ (CelValue::Bytes(_) | CelValue::String(_)), + right @ (CelValue::Bytes(_) | CelValue::String(_)), + ) => { let r = match &right { CelValue::Bytes(b) => b.as_ref(), CelValue::String(s) => s.as_ref().as_bytes(), @@ -406,9 +506,15 @@ impl<'a> CelValue<'a> { } } - pub fn cel_ends_with(left: impl CelValueConv<'a>, right: impl CelValueConv<'a>) -> Result> { + pub fn cel_ends_with( + left: impl CelValueConv<'a>, + right: impl CelValueConv<'a>, + ) -> Result> { match (left.conv(), right.conv()) { - (left @ (CelValue::Bytes(_) | CelValue::String(_)), right @ (CelValue::Bytes(_) | CelValue::String(_))) => { + ( + left @ (CelValue::Bytes(_) | CelValue::String(_)), + right @ (CelValue::Bytes(_) | CelValue::String(_)), + ) => { let r = match &right { CelValue::Bytes(b) => b.as_ref(), CelValue::String(s) => s.as_ref().as_bytes(), @@ -431,7 +537,10 @@ impl<'a> CelValue<'a> { } } - pub fn cel_matches(value: impl CelValueConv<'a>, regex: ®ex::Regex) -> Result> { + pub fn cel_matches( + value: impl CelValueConv<'a>, + regex: ®ex::Regex, + ) -> Result> { match value.conv() { value @ (CelValue::Bytes(_) | CelValue::String(_)) => { let maybe_str = match &value { @@ -446,7 +555,10 @@ impl<'a> CelValue<'a> { Ok(regex.is_match(input)) } - value => Err(CelError::BadUnaryOperation { op: "matches", value }), + value => Err(CelError::BadUnaryOperation { + op: "matches", + value, + }), } } @@ -462,7 +574,10 @@ impl<'a> CelValue<'a> { Ok(false) } } - value => Err(CelError::BadUnaryOperation { op: "isIpv4", value }), + value => Err(CelError::BadUnaryOperation { + op: "isIpv4", + value, + }), } } @@ -478,7 +593,10 @@ impl<'a> CelValue<'a> { Ok(false) } } - value => Err(CelError::BadUnaryOperation { op: "isIpv6", value }), + value => Err(CelError::BadUnaryOperation { + op: "isIpv6", + value, + }), } } @@ -494,7 +612,10 @@ impl<'a> CelValue<'a> { Ok(false) } } - value => Err(CelError::BadUnaryOperation { op: "isUuid", value }), + value => Err(CelError::BadUnaryOperation { + op: "isUuid", + value, + }), } } @@ -510,7 +631,10 @@ impl<'a> CelValue<'a> { Ok(false) } } - value => Err(CelError::BadUnaryOperation { op: "isUlid", value }), + value => Err(CelError::BadUnaryOperation { + op: "isUlid", + value, + }), } } @@ -524,7 +648,10 @@ impl<'a> CelValue<'a> { Ok(false) } } - value => Err(CelError::BadUnaryOperation { op: "isHostname", value }), + value => Err(CelError::BadUnaryOperation { + op: "isHostname", + value, + }), } } @@ -552,7 +679,10 @@ impl<'a> CelValue<'a> { Ok(false) } } - value => Err(CelError::BadUnaryOperation { op: "isEmail", value }), + value => Err(CelError::BadUnaryOperation { + op: "isEmail", + value, + }), } } @@ -584,7 +714,10 @@ impl<'a> CelValue<'a> { Self::String(s) => Ok(s.as_ref().len() as u64), Self::List(l) => Ok(l.len() as u64), Self::Map(m) => Ok(m.len() as u64), - item => Err(CelError::BadUnaryOperation { op: "size", value: item }), + item => Err(CelError::BadUnaryOperation { + op: "size", + value: item, + }), } } @@ -593,7 +726,13 @@ impl<'a> CelValue<'a> { map_fn: impl Fn(CelValue<'a>) -> Result, CelError<'a>>, ) -> Result, CelError<'a>> { match item.conv() { - CelValue::List(items) => Ok(CelValue::List(items.iter().cloned().map(map_fn).collect::>()?)), + CelValue::List(items) => Ok(CelValue::List( + items + .iter() + .cloned() + .map(map_fn) + .collect::>()?, + )), CelValue::Map(map) => Ok(CelValue::List( map.iter() .map(|(key, _)| key) @@ -617,7 +756,11 @@ impl<'a> CelValue<'a> { match item.conv() { CelValue::List(items) => Ok(CelValue::List( - items.iter().cloned().filter_map(filter_map).collect::>()?, + items + .iter() + .cloned() + .filter_map(filter_map) + .collect::>()?, )), CelValue::Map(map) => Ok(CelValue::List( map.iter() @@ -626,7 +769,10 @@ impl<'a> CelValue<'a> { .filter_map(filter_map) .collect::>()?, )), - value => Err(CelError::BadUnaryOperation { op: "filter", value }), + value => Err(CelError::BadUnaryOperation { + op: "filter", + value, + }), } } @@ -678,7 +824,10 @@ impl<'a> CelValue<'a> { match item.conv() { CelValue::List(items) => exists(items.iter().cloned(), map_fn), CelValue::Map(map) => exists(map.iter().map(|(key, _)| key).cloned(), map_fn), - value => Err(CelError::BadUnaryOperation { op: "existsOne", value }), + value => Err(CelError::BadUnaryOperation { + op: "existsOne", + value, + }), } } @@ -709,16 +858,19 @@ impl<'a> CelValue<'a> { match item.conv() { CelValue::List(items) => exists_one(items.iter().cloned(), map_fn), CelValue::Map(map) => exists_one(map.iter().map(|(key, _)| key).cloned(), map_fn), - value => Err(CelError::BadUnaryOperation { op: "existsOne", value }), + value => Err(CelError::BadUnaryOperation { + op: "existsOne", + value, + }), } } pub fn cel_to_string(item: impl CelValueConv<'a>) -> CelValue<'a> { match item.conv() { item @ CelValue::String(_) => item, - CelValue::Bytes(CelBytes::Owned(bytes)) => { - CelValue::String(CelString::Owned(String::from_utf8_lossy(bytes.as_ref()).into())) - } + CelValue::Bytes(CelBytes::Owned(bytes)) => CelValue::String(CelString::Owned( + String::from_utf8_lossy(bytes.as_ref()).into(), + )), CelValue::Bytes(CelBytes::Borrowed(b)) => match String::from_utf8_lossy(b) { Cow::Borrowed(b) => CelValue::String(CelString::Borrowed(b)), Cow::Owned(o) => CelValue::String(CelString::Owned(o.into())), @@ -730,8 +882,12 @@ impl<'a> CelValue<'a> { pub fn cel_to_bytes(item: impl CelValueConv<'a>) -> Result, CelError<'a>> { match item.conv() { item @ CelValue::Bytes(_) => Ok(item.clone()), - CelValue::String(CelString::Owned(s)) => Ok(CelValue::Bytes(CelBytes::Owned(s.as_bytes().to_vec().into()))), - CelValue::String(CelString::Borrowed(s)) => Ok(CelValue::Bytes(CelBytes::Borrowed(s.as_bytes()))), + CelValue::String(CelString::Owned(s)) => Ok(CelValue::Bytes(CelBytes::Owned( + s.as_bytes().to_vec().into(), + ))), + CelValue::String(CelString::Borrowed(s)) => { + Ok(CelValue::Bytes(CelBytes::Borrowed(s.as_bytes()))) + } value => Err(CelError::BadUnaryOperation { op: "bytes", value }), } } @@ -793,11 +949,17 @@ impl<'a> CelValue<'a> { Ok(CelValue::Null) } } - value => Err(CelError::BadUnaryOperation { op: "double", value }), + value => Err(CelError::BadUnaryOperation { + op: "double", + value, + }), } } - pub fn cel_to_enum(item: impl CelValueConv<'a>, path: impl CelValueConv<'a>) -> Result, CelError<'a>> { + pub fn cel_to_enum( + item: impl CelValueConv<'a>, + path: impl CelValueConv<'a>, + ) -> Result, CelError<'a>> { match (item.conv(), path.conv()) { (CelValue::Number(number), CelValue::String(tag)) => { let Some(value) = number.to_i32() else { @@ -806,7 +968,9 @@ impl<'a> CelValue<'a> { Ok(CelValue::Enum(CelEnum { tag, value })) } - (CelValue::Enum(CelEnum { value, .. }), CelValue::String(tag)) => Ok(CelValue::Enum(CelEnum { tag, value })), + (CelValue::Enum(CelEnum { value, .. }), CelValue::String(tag)) => { + Ok(CelValue::Enum(CelEnum { tag, value })) + } (value, path) => Err(CelError::BadOperation { op: "enum", left: value, @@ -820,7 +984,10 @@ impl PartialEq for CelValue<'_> { fn eq(&self, other: &Self) -> bool { match (self, other) { (CelValue::Bool(left), CelValue::Bool(right)) => left == right, - (left @ (CelValue::Bytes(_) | CelValue::String(_)), right @ (CelValue::Bytes(_) | CelValue::String(_))) => { + ( + left @ (CelValue::Bytes(_) | CelValue::String(_)), + right @ (CelValue::Bytes(_) | CelValue::String(_)), + ) => { let left = match left { CelValue::String(s) => s.as_bytes(), CelValue::Bytes(b) => b.as_ref(), @@ -836,14 +1003,14 @@ impl PartialEq for CelValue<'_> { left == right } (CelValue::Duration(left), CelValue::Duration(right)) => left == right, - (CelValue::Duration(dur), CelValue::Number(seconds)) | (CelValue::Number(seconds), CelValue::Duration(dur)) => { + (CelValue::Duration(dur), CelValue::Number(seconds)) + | (CelValue::Number(seconds), CelValue::Duration(dur)) => { (dur.num_seconds() as f64) + dur.subsec_nanos() as f64 / 1_000_000_000.0 == *seconds } (CelValue::Timestamp(left), CelValue::Timestamp(right)) => left == right, (CelValue::Enum(left), CelValue::Enum(right)) => left == right, - (CelValue::Enum(enum_), CelValue::Number(value)) | (CelValue::Number(value), CelValue::Enum(enum_)) => { - enum_.value == *value - } + (CelValue::Enum(enum_), CelValue::Number(value)) + | (CelValue::Number(value), CelValue::Enum(enum_)) => enum_.value == *value, (CelValue::List(left), CelValue::List(right)) => left == right, (CelValue::Map(left), CelValue::Map(right)) => left == right, (CelValue::Number(left), CelValue::Number(right)) => left == right, @@ -1000,7 +1167,10 @@ impl std::fmt::Display for CelValue<'_> { CelValue::Map(m) => { let mut map = f.debug_map(); for (key, value) in m.iter() { - map.entry(&fmtools::fmt(|fmt| key.fmt(fmt)), &fmtools::fmt(|fmt| value.fmt(fmt))); + map.entry( + &fmtools::fmt(|fmt| key.fmt(fmt)), + &fmtools::fmt(|fmt| value.fmt(fmt)), + ); } map.finish() } @@ -1047,11 +1217,13 @@ impl PartialOrd for NumberTy { NumberTy::promote(*self, *other).and_then(|(l, r)| match (l, r) { (NumberTy::I64(l), NumberTy::I64(r)) => Some(l.cmp(&r)), (NumberTy::U64(l), NumberTy::U64(r)) => Some(l.cmp(&r)), - (NumberTy::F64(l), NumberTy::F64(r)) => Some(if l.approx_eq(r, float_cmp::F64Margin::default()) { - std::cmp::Ordering::Equal - } else { - l.partial_cmp(&r).unwrap_or(std::cmp::Ordering::Equal) - }), + (NumberTy::F64(l), NumberTy::F64(r)) => { + Some(if l.approx_eq(r, float_cmp::F64Margin::default()) { + std::cmp::Ordering::Equal + } else { + l.partial_cmp(&r).unwrap_or(std::cmp::Ordering::Equal) + }) + } // I think this is unreachable _ => None, }) @@ -1062,8 +1234,12 @@ impl NumberTy { pub fn cel_add(self, other: Self) -> Result> { const ERROR: CelError<'static> = CelError::NumberOutOfRange { op: "addition" }; match NumberTy::promote(self, other).ok_or(ERROR)? { - (NumberTy::I64(l), NumberTy::I64(r)) => Ok(NumberTy::I64(l.checked_add(r).ok_or(ERROR)?)), - (NumberTy::U64(l), NumberTy::U64(r)) => Ok(NumberTy::U64(l.checked_add(r).ok_or(ERROR)?)), + (NumberTy::I64(l), NumberTy::I64(r)) => { + Ok(NumberTy::I64(l.checked_add(r).ok_or(ERROR)?)) + } + (NumberTy::U64(l), NumberTy::U64(r)) => { + Ok(NumberTy::U64(l.checked_add(r).ok_or(ERROR)?)) + } (NumberTy::F64(l), NumberTy::F64(r)) => Ok(NumberTy::F64(l + r)), // I think this is unreachable _ => Err(ERROR), @@ -1073,8 +1249,12 @@ impl NumberTy { pub fn cel_sub(self, other: Self) -> Result> { const ERROR: CelError<'static> = CelError::NumberOutOfRange { op: "subtraction" }; match NumberTy::promote(self, other).ok_or(ERROR)? { - (NumberTy::I64(l), NumberTy::I64(r)) => Ok(NumberTy::I64(l.checked_sub(r).ok_or(ERROR)?)), - (NumberTy::U64(l), NumberTy::U64(r)) => Ok(NumberTy::U64(l.checked_sub(r).ok_or(ERROR)?)), + (NumberTy::I64(l), NumberTy::I64(r)) => { + Ok(NumberTy::I64(l.checked_sub(r).ok_or(ERROR)?)) + } + (NumberTy::U64(l), NumberTy::U64(r)) => { + Ok(NumberTy::U64(l.checked_sub(r).ok_or(ERROR)?)) + } (NumberTy::F64(l), NumberTy::F64(r)) => Ok(NumberTy::F64(l - r)), // I think this is unreachable _ => Err(ERROR), @@ -1082,10 +1262,16 @@ impl NumberTy { } pub fn cel_mul(self, other: Self) -> Result> { - const ERROR: CelError<'static> = CelError::NumberOutOfRange { op: "multiplication" }; + const ERROR: CelError<'static> = CelError::NumberOutOfRange { + op: "multiplication", + }; match NumberTy::promote(self, other).ok_or(ERROR)? { - (NumberTy::I64(l), NumberTy::I64(r)) => Ok(NumberTy::I64(l.checked_mul(r).ok_or(ERROR)?)), - (NumberTy::U64(l), NumberTy::U64(r)) => Ok(NumberTy::U64(l.checked_mul(r).ok_or(ERROR)?)), + (NumberTy::I64(l), NumberTy::I64(r)) => { + Ok(NumberTy::I64(l.checked_mul(r).ok_or(ERROR)?)) + } + (NumberTy::U64(l), NumberTy::U64(r)) => { + Ok(NumberTy::U64(l.checked_mul(r).ok_or(ERROR)?)) + } (NumberTy::F64(l), NumberTy::F64(r)) => Ok(NumberTy::F64(l * r)), // I think this is unreachable _ => Err(ERROR), @@ -1094,13 +1280,19 @@ impl NumberTy { pub fn cel_div(self, other: Self) -> Result> { if other == 0 { - return Err(CelError::NumberOutOfRange { op: "division by zero" }); + return Err(CelError::NumberOutOfRange { + op: "division by zero", + }); } const ERROR: CelError<'static> = CelError::NumberOutOfRange { op: "division" }; match NumberTy::promote(self, other).ok_or(ERROR)? { - (NumberTy::I64(l), NumberTy::I64(r)) => Ok(NumberTy::I64(l.checked_div(r).ok_or(ERROR)?)), - (NumberTy::U64(l), NumberTy::U64(r)) => Ok(NumberTy::U64(l.checked_div(r).ok_or(ERROR)?)), + (NumberTy::I64(l), NumberTy::I64(r)) => { + Ok(NumberTy::I64(l.checked_div(r).ok_or(ERROR)?)) + } + (NumberTy::U64(l), NumberTy::U64(r)) => { + Ok(NumberTy::U64(l.checked_div(r).ok_or(ERROR)?)) + } (NumberTy::F64(l), NumberTy::F64(r)) => Ok(NumberTy::F64(l / r)), // I think this is unreachable _ => Err(ERROR), @@ -1109,13 +1301,19 @@ impl NumberTy { pub fn cel_rem(self, other: Self) -> Result> { if other == 0 { - return Err(CelError::NumberOutOfRange { op: "remainder by zero" }); + return Err(CelError::NumberOutOfRange { + op: "remainder by zero", + }); } const ERROR: CelError<'static> = CelError::NumberOutOfRange { op: "remainder" }; match NumberTy::promote(self, other).ok_or(ERROR)? { - (NumberTy::I64(l), NumberTy::I64(r)) => Ok(NumberTy::I64(l.checked_rem(r).ok_or(ERROR)?)), - (NumberTy::U64(l), NumberTy::U64(r)) => Ok(NumberTy::U64(l.checked_rem(r).ok_or(ERROR)?)), + (NumberTy::I64(l), NumberTy::I64(r)) => { + Ok(NumberTy::I64(l.checked_rem(r).ok_or(ERROR)?)) + } + (NumberTy::U64(l), NumberTy::U64(r)) => { + Ok(NumberTy::U64(l.checked_rem(r).ok_or(ERROR)?)) + } _ => Err(ERROR), } } @@ -1124,7 +1322,9 @@ impl NumberTy { const ERROR: CelError<'static> = CelError::NumberOutOfRange { op: "negation" }; match self { NumberTy::I64(n) => Ok(NumberTy::I64(n.checked_neg().ok_or(ERROR)?)), - NumberTy::U64(n) => Ok(NumberTy::I64(n.to_i64().ok_or(ERROR)?.checked_neg().ok_or(ERROR)?)), + NumberTy::U64(n) => Ok(NumberTy::I64( + n.to_i64().ok_or(ERROR)?.checked_neg().ok_or(ERROR)?, + )), NumberTy::F64(n) => Ok(NumberTy::F64(-n)), } } @@ -1173,7 +1373,9 @@ impl PartialEq for NumberTy { .map(|(l, r)| match (l, r) { (NumberTy::I64(l), NumberTy::I64(r)) => l == r, (NumberTy::U64(l), NumberTy::U64(r)) => l == r, - (NumberTy::F64(l), NumberTy::F64(r)) => l.approx_eq(r, float_cmp::F64Margin::default()), + (NumberTy::F64(l), NumberTy::F64(r)) => { + l.approx_eq(r, float_cmp::F64Margin::default()) + } // I think this is unreachable _ => false, }) @@ -1292,16 +1494,25 @@ impl NumberTy { match (left, right) { (NumberTy::I64(l), NumberTy::I64(r)) => Some((NumberTy::I64(l), NumberTy::I64(r))), (NumberTy::U64(l), NumberTy::U64(r)) => Some((NumberTy::U64(l), NumberTy::U64(r))), - (NumberTy::F64(_), _) | (_, NumberTy::F64(_)) => Some((Self::F64(left.to_f64()?), Self::F64(right.to_f64()?))), - (NumberTy::I64(_), _) | (_, NumberTy::I64(_)) => Some((Self::I64(left.to_i64()?), Self::I64(right.to_i64()?))), + (NumberTy::F64(_), _) | (_, NumberTy::F64(_)) => { + Some((Self::F64(left.to_f64()?), Self::F64(right.to_f64()?))) + } + (NumberTy::I64(_), _) | (_, NumberTy::I64(_)) => { + Some((Self::I64(left.to_i64()?), Self::I64(right.to_i64()?))) + } } } } -pub fn array_access<'a, 'b, T>(array: &'a [T], idx: impl CelValueConv<'b>) -> Result<&'a T, CelError<'b>> { +pub fn array_access<'a, 'b, T>( + array: &'a [T], + idx: impl CelValueConv<'b>, +) -> Result<&'a T, CelError<'b>> { let idx = idx.conv(); match idx.as_number().and_then(|n| n.to_usize()) { - Some(idx) => array.get(idx).ok_or(CelError::IndexOutOfBounds(idx, array.len())), + Some(idx) => array + .get(idx) + .ok_or(CelError::IndexOutOfBounds(idx, array.len())), _ => Err(CelError::IndexWithBadIndex(idx)), } } @@ -1338,7 +1549,10 @@ impl PartialEq> for Bytes { } } -pub fn array_contains<'a, 'b, T: PartialEq>>(array: &'a [T], value: impl CelValueConv<'b>) -> bool { +pub fn array_contains<'a, 'b, T: PartialEq>>( + array: &'a [T], + value: impl CelValueConv<'b>, +) -> bool { let value = value.conv(); array.iter().any(|v| v == &value) } @@ -1417,7 +1631,10 @@ where } #[allow(private_bounds)] -pub fn map_access<'a, 'b, K, V>(map: &'a impl Map, key: impl CelValueConv<'b>) -> Result<&'a V, CelError<'b>> +pub fn map_access<'a, 'b, K, V>( + map: &'a impl Map, + key: impl CelValueConv<'b>, +) -> Result<&'a V, CelError<'b>> where K: Ord + Hash + MapKeyCast, K: std::borrow::Borrow, @@ -1588,7 +1805,12 @@ pub struct EnumVtable { impl EnumVtable { pub fn from_tag(tag: &str) -> Option<&'static EnumVtable> { static LOOKUP: std::sync::LazyLock> = - std::sync::LazyLock::new(|| TINC_CEL_ENUM_VTABLE.into_iter().map(|item| (item.proto_path, item)).collect()); + std::sync::LazyLock::new(|| { + TINC_CEL_ENUM_VTABLE + .into_iter() + .map(|item| (item.proto_path, item)) + .collect() + }); LOOKUP.get(tag).copied() } @@ -1614,8 +1836,8 @@ mod tests { use super::CelString; use crate::{ - CelBooleanConv, CelBytes, CelEnum, CelError, CelValue, CelValueConv, MapKeyCast, NumberTy, array_access, - array_contains, map_access, map_contains, + CelBooleanConv, CelBytes, CelEnum, CelError, CelValue, CelValueConv, MapKeyCast, NumberTy, + array_access, array_contains, map_access, map_contains, }; #[test] @@ -1871,7 +2093,10 @@ mod tests { assert_eq!(s, CelValue::String(CelString::Owned(Arc::from("foobar")))); // bytes let b = CelValue::cel_add(Bytes::from_static(b"ab"), Bytes::from_static(b"cd")).unwrap(); - assert_eq!(b, CelValue::Bytes(CelBytes::Owned(Bytes::from_static(b"abcd")))); + assert_eq!( + b, + CelValue::Bytes(CelBytes::Owned(Bytes::from_static(b"abcd"))) + ); // list let l = CelValue::cel_add(make_list(&[1, 2]), make_list(&[3])).unwrap(); assert_eq!(l, make_list(&[1, 2, 3])); @@ -2014,7 +2239,11 @@ mod tests { assert!(CelValue::cel_matches(b, &re).unwrap()); // non-utf8 bytes -> Ok(false) - let bad = CelValue::cel_matches(Bytes::from_static(&[0xff, 0xfe]), &Regex::new(".*").unwrap()).unwrap(); + let bad = CelValue::cel_matches( + Bytes::from_static(&[0xff, 0xfe]), + &Regex::new(".*").unwrap(), + ) + .unwrap(); assert!(!bad); let err = CelValue::cel_matches(1i32, &re).unwrap_err(); @@ -2217,8 +2446,10 @@ mod tests { assert_eq!(keys, [10, 20].conv()); // filter: keep evens - let f = - CelValue::cel_filter([1, 2, 3, 4].conv(), |v| Ok(v.as_number().unwrap().to_i64().unwrap() % 2 == 0)).unwrap(); + let f = CelValue::cel_filter([1, 2, 3, 4].conv(), |v| { + Ok(v.as_number().unwrap().to_i64().unwrap() % 2 == 0) + }) + .unwrap(); assert_eq!(f, [2, 4].conv()); // filter on map => list of keys @@ -2241,7 +2472,10 @@ mod tests { let err = CelValue::cel_filter(list, |v| { if v == 2i32.conv() { - Err(CelError::BadUnaryOperation { op: "test", value: v }) + Err(CelError::BadUnaryOperation { + op: "test", + value: v, + }) } else { Ok(true) } @@ -2259,19 +2493,27 @@ mod tests { #[test] fn celvalue_list_and_map_all() { let list = [1, 2, 3].conv(); - let all_pos = CelValue::cel_all(list.clone(), |v| Ok(v.as_number().unwrap().to_i64().unwrap() > 0)).unwrap(); + let all_pos = CelValue::cel_all(list.clone(), |v| { + Ok(v.as_number().unwrap().to_i64().unwrap() > 0) + }) + .unwrap(); assert!(all_pos); let list2 = [1, 0, 3].conv(); - let any_zero = CelValue::cel_all(list2, |v| Ok(v.as_number().unwrap().to_i64().unwrap() > 0)).unwrap(); + let any_zero = + CelValue::cel_all(list2, |v| Ok(v.as_number().unwrap().to_i64().unwrap() > 0)).unwrap(); assert!(!any_zero); let map = as_map(&[(2, 20), (4, 40)]); - let all_keys = CelValue::cel_all(map.clone(), |v| Ok(v.as_number().unwrap().to_i64().unwrap() < 5)).unwrap(); + let all_keys = CelValue::cel_all(map.clone(), |v| { + Ok(v.as_number().unwrap().to_i64().unwrap() < 5) + }) + .unwrap(); assert!(all_keys); let map2 = as_map(&[(2, 20), (6, 60)]); - let some_ge5 = CelValue::cel_all(map2, |v| Ok(v.as_number().unwrap().to_i64().unwrap() < 5)).unwrap(); + let some_ge5 = + CelValue::cel_all(map2, |v| Ok(v.as_number().unwrap().to_i64().unwrap() < 5)).unwrap(); assert!(!some_ge5); } @@ -2495,7 +2737,10 @@ mod tests { assert_eq!(out_num, CelValue::String(CelString::Owned(Arc::from("42")))); let out_bool = CelValue::cel_to_string(true); - assert_eq!(out_bool, CelValue::String(CelString::Owned(Arc::from("true")))); + assert_eq!( + out_bool, + CelValue::String(CelString::Owned(Arc::from("true"))) + ); } #[test] @@ -2628,7 +2873,10 @@ mod tests { #[test] fn celvalue_to_double_from_string_valid() { let result = CelValue::cel_to_double("3.141592653589793").unwrap(); - assert_eq!(result, CelValue::Number(NumberTy::F64(std::f64::consts::PI))); + assert_eq!( + result, + CelValue::Number(NumberTy::F64(std::f64::consts::PI)) + ); } #[test] @@ -2646,7 +2894,10 @@ mod tests { #[test] fn celvalue_to_double_from_f64_number() { let result = CelValue::cel_to_double(std::f64::consts::PI).unwrap(); - assert_eq!(result, CelValue::Number(NumberTy::F64(std::f64::consts::PI))); + assert_eq!( + result, + CelValue::Number(NumberTy::F64(std::f64::consts::PI)) + ); } #[test] @@ -2736,8 +2987,10 @@ mod tests { fn celvalue_eq_timestamp_variants() { use chrono::{DateTime, FixedOffset}; - let dt1: DateTime = DateTime::parse_from_rfc3339("2021-01-01T12:00:00+00:00").unwrap(); - let dt2: DateTime = DateTime::parse_from_rfc3339("2021-01-01T12:00:00+00:00").unwrap(); + let dt1: DateTime = + DateTime::parse_from_rfc3339("2021-01-01T12:00:00+00:00").unwrap(); + let dt2: DateTime = + DateTime::parse_from_rfc3339("2021-01-01T12:00:00+00:00").unwrap(); let t1 = CelValue::Timestamp(dt1); let t2 = CelValue::Timestamp(dt2); @@ -2759,8 +3012,14 @@ mod tests { let list2 = (&[1, 2, 3][..]).conv(); assert_eq!(list1, list2); - let map1 = CelValue::Map(Arc::from(vec![(1i32.conv(), 10i32.conv()), (2i32.conv(), 20i32.conv())])); - let map2 = CelValue::Map(Arc::from(vec![(1i32.conv(), 10i32.conv()), (2i32.conv(), 20i32.conv())])); + let map1 = CelValue::Map(Arc::from(vec![ + (1i32.conv(), 10i32.conv()), + (2i32.conv(), 20i32.conv()), + ])); + let map2 = CelValue::Map(Arc::from(vec![ + (1i32.conv(), 10i32.conv()), + (2i32.conv(), 20i32.conv()), + ])); assert_eq!(map1, map2); } @@ -2788,10 +3047,14 @@ mod tests { #[test] fn celvalue_display() { - let ts: DateTime = DateTime::parse_from_rfc3339("2025-05-04T00:00:00+00:00").unwrap(); + let ts: DateTime = + DateTime::parse_from_rfc3339("2025-05-04T00:00:00+00:00").unwrap(); // Build a simple map: {1: "x", 2: "y"} - let map_val = CelValue::Map(Arc::from(vec![(1i32.conv(), "x".conv()), (2i32.conv(), "y".conv())])); + let map_val = CelValue::Map(Arc::from(vec![ + (1i32.conv(), "x".conv()), + (2i32.conv(), "y".conv()), + ])); let outputs = [ format!("{}", CelValue::Bool(false)), @@ -2861,7 +3124,9 @@ mod tests { // Map let non_empty_map = CelValue::Map(Arc::from(vec![(1i32.conv(), 2i32.conv())])); assert!(non_empty_map.to_bool()); - let empty_map = CelValue::Map(Arc::from(Vec::<(CelValue, CelValue)>::new().into_boxed_slice())); + let empty_map = CelValue::Map(Arc::from( + Vec::<(CelValue, CelValue)>::new().into_boxed_slice(), + )); assert!(!empty_map.to_bool()); // Null @@ -2872,9 +3137,11 @@ mod tests { assert!(!CelValue::Duration(Duration::zero()).to_bool()); // Timestamp - let epoch: DateTime = DateTime::parse_from_rfc3339("1970-01-01T00:00:00+00:00").unwrap(); + let epoch: DateTime = + DateTime::parse_from_rfc3339("1970-01-01T00:00:00+00:00").unwrap(); assert!(!CelValue::Timestamp(epoch).to_bool()); - let later: DateTime = DateTime::parse_from_rfc3339("2025-05-04T00:00:00+00:00").unwrap(); + let later: DateTime = + DateTime::parse_from_rfc3339("2025-05-04T00:00:00+00:00").unwrap(); assert!(CelValue::Timestamp(later).to_bool()); } @@ -3414,12 +3681,24 @@ mod tests { CelMode::set(CelMode::Serde); let current = CelMode::current(); - assert!(current.is_json(), "CelMode should report JSON when set to Json"); - assert!(!current.is_proto(), "CelMode should not report Proto when set to Json"); + assert!( + current.is_json(), + "CelMode should report JSON when set to Json" + ); + assert!( + !current.is_proto(), + "CelMode should not report Proto when set to Json" + ); CelMode::set(CelMode::Proto); let current = CelMode::current(); - assert!(current.is_proto(), "CelMode should report Proto when set to Proto"); - assert!(!current.is_json(), "CelMode should not report JSON when set to Proto"); + assert!( + current.is_proto(), + "CelMode should report Proto when set to Proto" + ); + assert!( + !current.is_json(), + "CelMode should not report JSON when set to Proto" + ); } } diff --git a/tinc-integration-tests/build.rs b/tinc-integration-tests/build.rs index 49f9177..2a5e5d2 100644 --- a/tinc-integration-tests/build.rs +++ b/tinc-integration-tests/build.rs @@ -6,8 +6,12 @@ fn main() { config .btree_map(".") .float_with_non_finite_vals(".floats.FloatMessageWithNonFinite") - .float_with_non_finite_vals(".floats.FloatMessageWithSomeNonFinite.f32_with_non_finite_serializer") - .float_with_non_finite_vals(".floats.FloatMessageWithSomeNonFinite.f64_with_non_finite_serializer") + .float_with_non_finite_vals( + ".floats.FloatMessageWithSomeNonFinite.f32_with_non_finite_serializer", + ) + .float_with_non_finite_vals( + ".floats.FloatMessageWithSomeNonFinite.f64_with_non_finite_serializer", + ) .float_with_non_finite_vals(".expressions.FloatExpressions") .float_with_non_finite_vals(".expressions.DoubleExpressions"); diff --git a/tinc-integration-tests/src/advanced_service.rs b/tinc-integration-tests/src/advanced_service.rs index 6c2404a..f349efa 100644 --- a/tinc-integration-tests/src/advanced_service.rs +++ b/tinc-integration-tests/src/advanced_service.rs @@ -46,7 +46,10 @@ impl pb::advanced_service_server::AdvancedService for Svc { Ok(pb::UpdateUserResponse { user_id: req.user_id.clone(), username: "testuser".into(), - email: req.email.clone().unwrap_or_else(|| "test@example.com".into()), + email: req + .email + .clone() + .unwrap_or_else(|| "test@example.com".into()), display_name: req.display_name.clone(), } .into()) @@ -176,7 +179,9 @@ fn test_create_user_username_pattern() { email: "test@example.com".into(), display_name: None, }; - state.in_scope(|| invalid_start_number.validate(None)).unwrap(); + state + .in_scope(|| invalid_start_number.validate(None)) + .unwrap(); insta::assert_debug_snapshot!(state, @r#" TrackerSharedState { diff --git a/tinc-integration-tests/src/bytes_service.rs b/tinc-integration-tests/src/bytes_service.rs index 18bf684..1ba941e 100644 --- a/tinc-integration-tests/src/bytes_service.rs +++ b/tinc-integration-tests/src/bytes_service.rs @@ -12,15 +12,19 @@ struct Svc {} #[tonic::async_trait] impl pb::bytes_service_server::BytesService for Svc { - async fn bytes(&self, request: tonic::Request) -> tonic::Result> { + async fn bytes( + &self, + request: tonic::Request, + ) -> tonic::Result> { Ok(request.into_inner().into()) } } #[tokio::test] async fn test_bytes_service_grpc() { - let mut client = - pb::bytes_service_client::BytesServiceClient::new(pb::bytes_service_server::BytesServiceServer::new(Svc {})); + let mut client = pb::bytes_service_client::BytesServiceClient::new( + pb::bytes_service_server::BytesServiceServer::new(Svc {}), + ); let response = client .bytes(pb::BytesPayload { @@ -50,7 +54,9 @@ async fn test_bytes_service_rest_post_json() { let resp = client.call(req).await.unwrap(); assert_eq!( - resp.headers().get(http::header::CONTENT_TYPE).map(|h| h.as_bytes()), + resp.headers() + .get(http::header::CONTENT_TYPE) + .map(|h| h.as_bytes()), Some(b"application/json" as &[u8]) ); @@ -72,13 +78,17 @@ async fn test_bytes_service_rest_post_binary() { .uri("/upload") .method("POST") .header(http::header::CONTENT_TYPE, "some-random-content-type/xd") - .body(http_body_util::Full::new(bytes::Bytes::from(random_data.clone()))) + .body(http_body_util::Full::new(bytes::Bytes::from( + random_data.clone(), + ))) .unwrap(); let resp = client.call(req).await.unwrap(); assert_eq!( - resp.headers().get(http::header::CONTENT_TYPE).map(|h| h.as_bytes()), + resp.headers() + .get(http::header::CONTENT_TYPE) + .map(|h| h.as_bytes()), Some(b"some-random-content-type/xd" as &[u8]) ); diff --git a/tinc-integration-tests/src/expressions.rs b/tinc-integration-tests/src/expressions.rs index 2f69692..dea72cb 100644 --- a/tinc-integration-tests/src/expressions.rs +++ b/tinc-integration-tests/src/expressions.rs @@ -1033,7 +1033,9 @@ fn test_map_expressions_invalid() { fn test_message_expressions_valid() { let mut state = TrackerSharedState::default(); let valid = pb::MessageExpressions { - message: Some(pb::message_expressions::SubMessage { name: "troy".into() }), + message: Some(pb::message_expressions::SubMessage { + name: "troy".into(), + }), }; state.in_scope(|| valid.validate(None)).unwrap(); @@ -1096,7 +1098,9 @@ fn test_message_expressions_invalid() { fn test_repeated_message_expressions_valid() { let mut state = TrackerSharedState::default(); let valid = pb::RepeatedMessageExpressions { - messages: vec![pb::repeated_message_expressions::SubMessage { name: "troy".into() }], + messages: vec![pb::repeated_message_expressions::SubMessage { + name: "troy".into(), + }], }; state.in_scope(|| valid.validate(None)).unwrap(); @@ -1143,7 +1147,9 @@ fn test_map_message_expressions_valid() { map.insert( "first".into(), - pb::map_message_expressions::SubMessage { name: "troy".into() }, + pb::map_message_expressions::SubMessage { + name: "troy".into(), + }, ); map @@ -1167,7 +1173,10 @@ fn test_map_message_expressions_invalid() { messages: { let mut map = BTreeMap::new(); - map.insert("first".into(), pb::map_message_expressions::SubMessage { name: "tr".into() }); + map.insert( + "first".into(), + pb::map_message_expressions::SubMessage { name: "tr".into() }, + ); map }, diff --git a/tinc-integration-tests/src/optional_fields.rs b/tinc-integration-tests/src/optional_fields.rs index 5475d65..0f75a91 100644 --- a/tinc-integration-tests/src/optional_fields.rs +++ b/tinc-integration-tests/src/optional_fields.rs @@ -1,4 +1,4 @@ -use tinc::__private::{TrackerFor, TrackerSharedState, TincValidate, deserialize_tracker_target}; +use tinc::__private::{TincValidate, TrackerFor, TrackerSharedState, deserialize_tracker_target}; mod pb { #![allow(clippy::all)] diff --git a/tinc-integration-tests/src/renamed.rs b/tinc-integration-tests/src/renamed.rs index d25b8b2..8f06c23 100644 --- a/tinc-integration-tests/src/renamed.rs +++ b/tinc-integration-tests/src/renamed.rs @@ -25,7 +25,8 @@ macro_rules! create_rename_test { #[test] fn test_screaming_snake_case() { - let (state, value, tracker) = create_rename_test!(pb::ScreamingSnakeCaseMessage, "MY_CUSTOM_FIELD"); + let (state, value, tracker) = + create_rename_test!(pb::ScreamingSnakeCaseMessage, "MY_CUSTOM_FIELD"); insta::assert_debug_snapshot!(state, @r" TrackerSharedState { fail_fast: false, @@ -205,7 +206,8 @@ fn test_kebab_case() { #[test] fn test_screaming_kebab_case() { - let (state, value, tracker) = create_rename_test!(pb::ScreamingKebabCaseMessage, "MY-CUSTOM-FIELD"); + let (state, value, tracker) = + create_rename_test!(pb::ScreamingKebabCaseMessage, "MY-CUSTOM-FIELD"); insta::assert_debug_snapshot!(state, @r" TrackerSharedState { fail_fast: false, diff --git a/tinc-integration-tests/src/simple_service.rs b/tinc-integration-tests/src/simple_service.rs index 4581cef..a9b7a6b 100644 --- a/tinc-integration-tests/src/simple_service.rs +++ b/tinc-integration-tests/src/simple_service.rs @@ -11,7 +11,10 @@ struct Svc {} #[tonic::async_trait] impl pb::simple_service_server::SimpleService for Svc { - async fn ping(&self, request: tonic::Request) -> tonic::Result> { + async fn ping( + &self, + request: tonic::Request, + ) -> tonic::Result> { Ok(pb::PingResponse { result: format!("{} - pong", request.get_ref().arg), } @@ -21,10 +24,14 @@ impl pb::simple_service_server::SimpleService for Svc { #[tokio::test] async fn test_simple_service_grpc() { - let mut client = - pb::simple_service_client::SimpleServiceClient::new(pb::simple_service_server::SimpleServiceServer::new(Svc {})); + let mut client = pb::simple_service_client::SimpleServiceClient::new( + pb::simple_service_server::SimpleServiceServer::new(Svc {}), + ); - let response = client.ping(pb::PingRequest { arg: "grpc".into() }).await.unwrap(); + let response = client + .ping(pb::PingRequest { arg: "grpc".into() }) + .await + .unwrap(); assert_eq!(response.get_ref().result, "grpc - pong"); } @@ -45,7 +52,9 @@ async fn test_simple_service_rest_post() { let resp = client.call(req).await.unwrap(); assert_eq!( - resp.headers().get(http::header::CONTENT_TYPE).map(|h| h.as_bytes()), + resp.headers() + .get(http::header::CONTENT_TYPE) + .map(|h| h.as_bytes()), Some(b"application/json" as &[u8]) ); @@ -68,7 +77,9 @@ async fn test_simple_service_rest_get() { let resp = client.call(req).await.unwrap(); assert_eq!( - resp.headers().get(http::header::CONTENT_TYPE).map(|h| h.as_bytes()), + resp.headers() + .get(http::header::CONTENT_TYPE) + .map(|h| h.as_bytes()), Some(b"application/json" as &[u8]) ); diff --git a/tinc-pb-prost/build.rs b/tinc-pb-prost/build.rs index ddfa7d9..e34d433 100644 --- a/tinc-pb-prost/build.rs +++ b/tinc-pb-prost/build.rs @@ -4,7 +4,8 @@ use prost_types::FileDescriptorSet; fn main() { println!("cargo:rerun-if-changed=./annotations.proto"); - let descriptor_out = std::path::PathBuf::from(std::env::var_os("OUT_DIR").unwrap()).join("tinc.annotations.pb"); + let descriptor_out = + std::path::PathBuf::from(std::env::var_os("OUT_DIR").unwrap()).join("tinc.annotations.pb"); if let Ok(pre_compiled_fd) = std::env::var("TINC_COMPILED_FD") { let data = std::fs::read(pre_compiled_fd).unwrap(); diff --git a/tinc-pb-prost/src/lib.rs b/tinc-pb-prost/src/lib.rs index 39cfa26..4f0ef2c 100644 --- a/tinc-pb-prost/src/lib.rs +++ b/tinc-pb-prost/src/lib.rs @@ -19,4 +19,5 @@ include!(concat!(env!("OUT_DIR"), "/tinc.rs")); /// The raw protobuf file pub const TINC_ANNOTATIONS: &str = include_str!("../annotations.proto"); /// Field descriptor binary -pub const TINC_ANNOTATIONS_PB: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/tinc.annotations.pb")); +pub const TINC_ANNOTATIONS_PB: &[u8] = + include_bytes!(concat!(env!("OUT_DIR"), "/tinc.annotations.pb")); diff --git a/tinc-proc-macro/src/message_tracker.rs b/tinc-proc-macro/src/message_tracker.rs index 3ca4099..a8348df 100644 --- a/tinc-proc-macro/src/message_tracker.rs +++ b/tinc-proc-macro/src/message_tracker.rs @@ -9,7 +9,9 @@ struct TincContainerOptions { } impl TincContainerOptions { - fn from_attributes<'a>(attrs: impl IntoIterator) -> syn::Result { + fn from_attributes<'a>( + attrs: impl IntoIterator, + ) -> syn::Result { let mut crate_ = None; let mut tagged = false; let mut with_non_finite_values = false; @@ -76,7 +78,9 @@ struct TincFieldOptions { } impl TincFieldOptions { - fn from_attributes<'a>(attrs: impl IntoIterator) -> syn::Result { + fn from_attributes<'a>( + attrs: impl IntoIterator, + ) -> syn::Result { let mut enum_ = None; let mut oneof = false; let mut with_non_finite_values = false; @@ -139,26 +143,42 @@ pub(crate) fn derive_message_tracker(input: TokenStream) -> TokenStream { match &input.data { syn::Data::Struct(data) => derive_message_tracker_struct(input.ident, opts, data), syn::Data::Enum(data) => derive_message_tracker_enum(input.ident, opts, data), - _ => syn::Error::new(input.span(), "Tracker can only be derived for structs or enums").into_compile_error(), + _ => syn::Error::new( + input.span(), + "Tracker can only be derived for structs or enums", + ) + .into_compile_error(), } } -fn derive_message_tracker_struct(ident: syn::Ident, opts: TincContainerOptions, data: &syn::DataStruct) -> TokenStream { +fn derive_message_tracker_struct( + ident: syn::Ident, + opts: TincContainerOptions, + data: &syn::DataStruct, +) -> TokenStream { let TincContainerOptions { crate_path, tagged, with_non_finite_values, } = opts; if tagged { - return syn::Error::new(ident.span(), "tagged can only be used on enums").into_compile_error(); + return syn::Error::new(ident.span(), "tagged can only be used on enums") + .into_compile_error(); } if with_non_finite_values { - return syn::Error::new(ident.span(), "with_non_finite_values can only be used on floats").into_compile_error(); + return syn::Error::new( + ident.span(), + "with_non_finite_values can only be used on floats", + ) + .into_compile_error(); } let syn::Fields::Named(fields) = &data.fields else { - return syn::Error::new(ident.span(), "Tracker can only be derived for structs with named fields") - .into_compile_error(); + return syn::Error::new( + ident.span(), + "Tracker can only be derived for structs with named fields", + ) + .into_compile_error(); }; let tracker_ident = syn::Ident::new(&format!("{ident}Tracker"), ident.span()); @@ -183,11 +203,16 @@ fn derive_message_tracker_struct(ident: syn::Ident, opts: TincContainerOptions, )); } if oneof && with_non_finite_values { - return Err(syn::Error::new(f.span(), "oneof cannot be set with with_non_finite_values")); + return Err(syn::Error::new( + f.span(), + "oneof cannot be set with with_non_finite_values", + )); } let ty = match enum_path { - Some(enum_path) => quote! { <#ty as #crate_path::__private::EnumHelper>::Target<#enum_path> }, + Some(enum_path) => { + quote! { <#ty as #crate_path::__private::EnumHelper>::Target<#enum_path> } + } None if oneof => quote! { <#ty as #crate_path::__private::OneOfHelper>::Target }, None if with_non_finite_values => { quote! { <#ty as #crate_path::__private::FloatWithNonFinDesHelper>::Target } @@ -230,7 +255,11 @@ fn derive_message_tracker_struct(ident: syn::Ident, opts: TincContainerOptions, } } -fn derive_message_tracker_enum(ident: syn::Ident, opts: TincContainerOptions, data: &syn::DataEnum) -> TokenStream { +fn derive_message_tracker_enum( + ident: syn::Ident, + opts: TincContainerOptions, + data: &syn::DataEnum, +) -> TokenStream { let TincContainerOptions { crate_path, tagged, @@ -239,7 +268,11 @@ fn derive_message_tracker_enum(ident: syn::Ident, opts: TincContainerOptions, da let tracker_ident = syn::Ident::new(&format!("{ident}Tracker"), ident.span()); if with_non_finite_values { - return syn::Error::new(ident.span(), "with_non_finite_values can only be used on floats").into_compile_error(); + return syn::Error::new( + ident.span(), + "with_non_finite_values can only be used on floats", + ) + .into_compile_error(); } let variants = data