From ba8c096976e70eb978088af273c1692e8c6e4626 Mon Sep 17 00:00:00 2001 From: Bruce Guenter Date: Thu, 23 Feb 2023 13:31:29 -0600 Subject: [PATCH] chore(config): Set up `ConfigurableRef` for schema functions (#16568) * Reduce visibility of some pub functions, and drop unused * Set up `struct ConfigurableRef` for config schema functions The config schema functions currently dispatch which configurable type to use based on a type parameter to the functions. In order to make this dispatch dynamic, a new `struct ConfigurableRef` is set up that contains references to the functions for a given type implementing `trait Configurable`. This is then used in the schema functions to dispatch their operation, eliminating the type bound. This will be used by a follow-up change to allow for dynamically registrable transforms. --- lib/vector-common/src/datetime.rs | 6 +- lib/vector-config-macros/src/configurable.rs | 16 +- lib/vector-config/src/configurable.rs | 54 +++++ lib/vector-config/src/external/indexmap.rs | 16 +- lib/vector-config/src/external/no_proxy.rs | 2 +- lib/vector-config/src/lib.rs | 2 +- lib/vector-config/src/schema_gen.rs | 209 ++++++++----------- lib/vector-config/src/stdlib.rs | 40 ++-- src/config/id.rs | 2 +- src/config/mod.rs | 2 +- src/config/sink.rs | 2 +- src/config/transform.rs | 2 +- src/serde.rs | 2 +- src/sinks/util/buffer/compression.rs | 14 +- src/sinks/util/service/concurrency.rs | 8 +- 15 files changed, 211 insertions(+), 166 deletions(-) diff --git a/lib/vector-common/src/datetime.rs b/lib/vector-common/src/datetime.rs index 571de3e932c7e..98ec495eba72f 100644 --- a/lib/vector-common/src/datetime.rs +++ b/lib/vector-common/src/datetime.rs @@ -6,7 +6,7 @@ use derivative::Derivative; use serde_json::Value; use vector_config::{ schema::{ - apply_metadata, generate_const_string_schema, generate_one_of_schema, + apply_base_metadata, generate_const_string_schema, generate_one_of_schema, get_or_generate_schema, SchemaGenerator, SchemaObject, }, Configurable, GenerateError, Metadata, ToValue, @@ -117,7 +117,7 @@ impl Configurable for TimeZone { let mut local_schema = generate_const_string_schema("local".to_string()); let mut local_metadata = Metadata::with_description("System local timezone."); local_metadata.add_custom_attribute(CustomAttribute::kv("logical_name", "Local")); - apply_metadata::<()>(&mut local_schema, local_metadata); + apply_base_metadata(&mut local_schema, local_metadata); let mut tz_metadata = Metadata::with_title("A named timezone."); tz_metadata.set_description( @@ -126,7 +126,7 @@ impl Configurable for TimeZone { [tzdb]: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones"#, ); tz_metadata.add_custom_attribute(CustomAttribute::kv("logical_name", "Named")); - let tz_schema = get_or_generate_schema::(gen, Some(tz_metadata))?; + let tz_schema = get_or_generate_schema(&Tz::as_configurable_ref(), gen, Some(tz_metadata))?; Ok(generate_one_of_schema(&[local_schema, tz_schema])) } diff --git a/lib/vector-config-macros/src/configurable.rs b/lib/vector-config-macros/src/configurable.rs index 5af5ae2d6d3d9..af658f98dd3e2 100644 --- a/lib/vector-config-macros/src/configurable.rs +++ b/lib/vector-config-macros/src/configurable.rs @@ -130,7 +130,11 @@ fn build_to_value_fn(_container: &Container<'_>) -> proc_macro2::TokenStream { fn build_virtual_newtype_schema_fn(virtual_ty: Type) -> proc_macro2::TokenStream { quote! { fn generate_schema(schema_gen: &::std::cell::RefCell<::vector_config::schema::SchemaGenerator>) -> std::result::Result<::vector_config::schema::SchemaObject, ::vector_config::GenerateError> { - ::vector_config::schema::get_or_generate_schema::<#virtual_ty>(schema_gen, None) + ::vector_config::schema::get_or_generate_schema( + &<#virtual_ty as ::vector_config::Configurable>::as_configurable_ref(), + schema_gen, + None, + ) } } } @@ -172,7 +176,11 @@ fn generate_struct_field(field: &Field<'_>) -> proc_macro2::TokenStream { let field_schema_ty = get_field_schema_ty(field); let spanned_generate_schema = quote_spanned! {field.span()=> - ::vector_config::schema::get_or_generate_schema::<#field_schema_ty>(schema_gen, Some(#field_metadata_ref))? + ::vector_config::schema::get_or_generate_schema( + &<#field_schema_ty as ::vector_config::Configurable>::as_configurable_ref(), + schema_gen, + Some(#field_metadata_ref), + )? }; quote! { @@ -928,7 +936,7 @@ fn generate_enum_variant_apply_metadata(variant: &Variant<'_>) -> proc_macro2::T quote! { #variant_metadata - ::vector_config::schema::apply_metadata::<()>(&mut subschema, #variant_metadata_ref); + ::vector_config::schema::apply_base_metadata(&mut subschema, #variant_metadata_ref); } } @@ -938,7 +946,7 @@ fn generate_enum_variant_tag_apply_metadata(variant: &Variant<'_>) -> proc_macro quote! { #variant_tag_metadata - ::vector_config::schema::apply_metadata::<()>(&mut tag_subschema, #variant_tag_metadata_ref); + ::vector_config::schema::apply_base_metadata(&mut tag_subschema, #variant_tag_metadata_ref); } } diff --git a/lib/vector-config/src/configurable.rs b/lib/vector-config/src/configurable.rs index 1c1f73a6afdf4..35d2c5d2e4baf 100644 --- a/lib/vector-config/src/configurable.rs +++ b/lib/vector-config/src/configurable.rs @@ -65,6 +65,14 @@ where /// If an error occurs while generating the schema, an error variant will be returned describing /// the issue. fn generate_schema(gen: &RefCell) -> Result; + + /// Create a new configurable reference table. + fn as_configurable_ref() -> ConfigurableRef + where + Self: 'static, + { + ConfigurableRef::new::() + } } /// A type that can be converted directly to a `serde_json::Value`. This is used when translating @@ -73,3 +81,49 @@ pub trait ToValue { /// Convert this value into a `serde_json::Value`. Must not fail. fn to_value(&self) -> Value; } + +/// A pseudo-reference to a type that can be represented in a Vector configuration. This is +/// composed of references to all the class trait functions. +pub struct ConfigurableRef { + // TODO: Turn this into a plain value once this is resolved: + // https://github.com/rust-lang/rust/issues/63084 + type_name: fn() -> &'static str, + // TODO: Turn this into a plain value once const trait functions are implemented + // Ref: https://github.com/rust-lang/rfcs/pull/911 + referenceable_name: fn() -> Option<&'static str>, + make_metadata: fn() -> Metadata, + validate_metadata: fn(&Metadata) -> Result<(), GenerateError>, + generate_schema: fn(&RefCell) -> Result, +} + +impl ConfigurableRef { + /// Create a new configurable reference table. + pub const fn new() -> Self { + Self { + type_name: std::any::type_name::, + referenceable_name: T::referenceable_name, + make_metadata: T::metadata, + validate_metadata: T::validate_metadata, + generate_schema: T::generate_schema, + } + } + + pub(crate) fn type_name(&self) -> &'static str { + (self.type_name)() + } + pub(crate) fn referenceable_name(&self) -> Option<&'static str> { + (self.referenceable_name)() + } + pub(crate) fn make_metadata(&self) -> Metadata { + (self.make_metadata)() + } + pub(crate) fn validate_metadata(&self, metadata: &Metadata) -> Result<(), GenerateError> { + (self.validate_metadata)(metadata) + } + pub(crate) fn generate_schema( + &self, + gen: &RefCell, + ) -> Result { + (self.generate_schema)(gen) + } +} diff --git a/lib/vector-config/src/external/indexmap.rs b/lib/vector-config/src/external/indexmap.rs index 9c6cd8357911d..d90e6ceedeb51 100644 --- a/lib/vector-config/src/external/indexmap.rs +++ b/lib/vector-config/src/external/indexmap.rs @@ -14,8 +14,8 @@ use crate::{ impl Configurable for IndexMap where - K: ConfigurableString + ToValue + std::hash::Hash + Eq, - V: Configurable + ToValue, + K: ConfigurableString + ToValue + std::hash::Hash + Eq + 'static, + V: Configurable + ToValue + 'static, { fn is_optional() -> bool { // A hashmap with required fields would be... an object. So if you want that, make a struct @@ -34,9 +34,13 @@ where fn generate_schema(gen: &RefCell) -> Result { // Make sure our key type is _truly_ a string schema. - assert_string_schema_for_map::(gen)?; + assert_string_schema_for_map( + &K::as_configurable_ref(), + gen, + std::any::type_name::(), + )?; - generate_map_schema::(gen) + generate_map_schema(&V::as_configurable_ref(), gen) } } @@ -56,7 +60,7 @@ where impl Configurable for IndexSet where - V: Configurable + ToValue + std::hash::Hash + Eq, + V: Configurable + ToValue + std::hash::Hash + Eq + 'static, { fn metadata() -> Metadata { Metadata::with_transparent(true) @@ -68,7 +72,7 @@ where } fn generate_schema(gen: &RefCell) -> Result { - generate_set_schema::(gen) + generate_set_schema(&V::as_configurable_ref(), gen) } } diff --git a/lib/vector-config/src/external/no_proxy.rs b/lib/vector-config/src/external/no_proxy.rs index 9dafe98d26602..e441e3ea607f3 100644 --- a/lib/vector-config/src/external/no_proxy.rs +++ b/lib/vector-config/src/external/no_proxy.rs @@ -17,7 +17,7 @@ impl Configurable for no_proxy::NoProxy { fn generate_schema(gen: &RefCell) -> Result { // `NoProxy` (de)serializes itself as a vector of strings, without any constraints on the string value itself, so // we just... do that. - generate_array_schema::(gen) + generate_array_schema(&String::as_configurable_ref(), gen) } } diff --git a/lib/vector-config/src/lib.rs b/lib/vector-config/src/lib.rs index f9dccccdb3892..c4892650fa0a5 100644 --- a/lib/vector-config/src/lib.rs +++ b/lib/vector-config/src/lib.rs @@ -135,7 +135,7 @@ pub use serde_json; pub mod component; mod configurable; -pub use self::configurable::{Configurable, ToValue}; +pub use self::configurable::{Configurable, ConfigurableRef, ToValue}; mod errors; pub use self::errors::{BoundDirection, GenerateError}; mod external; diff --git a/lib/vector-config/src/schema_gen.rs b/lib/vector-config/src/schema_gen.rs index 68555858d2b7b..4eec0d4f4b019 100644 --- a/lib/vector-config/src/schema_gen.rs +++ b/lib/vector-config/src/schema_gen.rs @@ -5,29 +5,31 @@ use serde_json::{Map, Value}; use vector_config_common::{attributes::CustomAttribute, schema::*}; use crate::{ - num::ConfigurableNumber, Configurable, ConfigurableString, GenerateError, Metadata, ToValue, + num::ConfigurableNumber, Configurable, ConfigurableRef, GenerateError, Metadata, ToValue, }; /// Applies metadata to the given schema. /// /// Metadata can include semantic information (title, description, etc), validation (min/max, allowable /// patterns, etc), as well as actual arbitrary key/value data. -pub fn apply_metadata(schema: &mut SchemaObject, metadata: Metadata) -where - T: Configurable, -{ - let base_metadata = T::metadata(); +pub fn apply_base_metadata(schema: &mut SchemaObject, metadata: Metadata) { + apply_metadata(&<()>::as_configurable_ref(), schema, metadata) +} + +fn apply_metadata(config: &ConfigurableRef, schema: &mut SchemaObject, metadata: Metadata) { + let type_name = config.type_name(); + let base_metadata = config.make_metadata(); // Calculate the title/description of this schema. // // If the given `metadata` has either a title or description present, we use both those values, - // even if one of them is `None`. If both are `None`, we try falling back to the bcargo fmtase metadata - // for `T`. + // even if one of them is `None`. If both are `None`, we try falling back to the base metadata + // for the configurable type. // // This ensures that per-field titles/descriptions can override the base title/description of - // `T`, without mixing and matching, as sometimes the base type's title/description is far too - // generic and muddles the output. Essentially, if the callsite decides to provide an overridden - // title/description, it controls the entire title/description. + // the type, without mixing and matching, as sometimes the base type's title/description is far + // too generic and muddles the output. Essentially, if the callsite decides to provide an + // overridden title/description, it controls the entire title/description. let (schema_title, schema_description) = if metadata.title().is_some() || metadata.description().is_some() { (metadata.title(), metadata.description()) @@ -38,15 +40,14 @@ where // A description _must_ be present, one way or another, _unless_ one of these two conditions is // met: // - the field is marked transparent - // - `T` is referenceable and _does_ have a description + // - the type is referenceable and _does_ have a description // // We panic otherwise. let has_referenceable_description = - T::referenceable_name().is_some() && base_metadata.description().is_some(); + config.referenceable_name().is_some() && base_metadata.description().is_some(); let is_transparent = base_metadata.transparent() || metadata.transparent(); if schema_description.is_none() && !is_transparent && !has_referenceable_description { - let type_name = std::any::type_name::(); - panic!("No description provided for `{}`! All `Configurable` types must define a description, or have one specified at the field-level where the type is being used.", type_name); + panic!("No description provided for `{type_name}`! All `Configurable` types must define a description, or have one specified at the field-level where the type is being used."); } // If a default value was given, serialize it. @@ -94,7 +95,7 @@ where Some(Value::Bool(_)) | None => {}, // Any other value being present means we're clashing with a different metadata // attribute, which is not good, so we have to bail out. - _ => panic!("Tried to set metadata flag '{}' but already existed in schema metadata for `{}`.", key, std::any::type_name::()), + _ => panic!("Tried to set metadata flag '{key}' but already existed in schema metadata for `{type_name}`."), } } CustomAttribute::KeyValue { key, value } => { @@ -103,7 +104,7 @@ where // We already have a flag entry for this key, which we cannot turn into an // array, so we panic in this particular case to signify the weirdness. Value::Bool(_) => { - panic!("Tried to overwrite metadata flag '{}' but already existed in schema metadata for `{}` as a flag.", key, std::any::type_name::()); + panic!("Tried to overwrite metadata flag '{key}' but already existed in schema metadata for `{type_name}` as a flag."); }, // The entry is already a multi-value KV pair, so just append the value. Value::Array(items) => { @@ -176,7 +177,7 @@ pub fn generate_string_schema() -> SchemaObject { pub fn generate_number_schema() -> SchemaObject where - N: Configurable + ConfigurableNumber, + N: ConfigurableNumber, { // TODO: Once `schemars` has proper integer support, we should allow specifying min/max bounds // in a way that's relevant to the number class. As is, we're always forcing bounds to fit into @@ -212,14 +213,12 @@ where schema } -pub fn generate_array_schema( +pub(crate) fn generate_array_schema( + config: &ConfigurableRef, gen: &RefCell, -) -> Result -where - T: Configurable, -{ - // Generate the actual schema for the element type `T`. - let element_schema = get_or_generate_schema::(gen, None)?; +) -> Result { + // Generate the actual schema for the element type. + let element_schema = get_or_generate_schema(config, gen, None)?; Ok(SchemaObject { instance_type: Some(InstanceType::Array.into()), @@ -231,12 +230,12 @@ where }) } -pub fn generate_set_schema(gen: &RefCell) -> Result -where - T: Configurable, -{ - // Generate the actual schema for the element type `T`. - let element_schema = get_or_generate_schema::(gen, None)?; +pub(crate) fn generate_set_schema( + config: &ConfigurableRef, + gen: &RefCell, +) -> Result { + // Generate the actual schema for the element type. + let element_schema = get_or_generate_schema(config, gen, None)?; Ok(SchemaObject { instance_type: Some(InstanceType::Array.into()), @@ -249,12 +248,12 @@ where }) } -pub fn generate_map_schema(gen: &RefCell) -> Result -where - V: Configurable, -{ - // Generate the actual schema for the element type `V`. - let element_schema = get_or_generate_schema::(gen, None)?; +pub(crate) fn generate_map_schema( + config: &ConfigurableRef, + gen: &RefCell, +) -> Result { + // Generate the actual schema for the element type. + let element_schema = get_or_generate_schema(config, gen, None)?; Ok(SchemaObject { instance_type: Some(InstanceType::Object.into()), @@ -287,12 +286,10 @@ pub fn generate_struct_schema( } } -pub fn generate_optional_schema( +pub(crate) fn generate_optional_schema( + config: &ConfigurableRef, gen: &RefCell, -) -> Result -where - T: Configurable, -{ +) -> Result { // Optional schemas are generally very simple in practice, but because of how we memoize schema // generation and use references to schema definitions, we have to handle quite a few cases // here. @@ -306,14 +303,14 @@ where // type already uses that mechanism // - create our own `oneOf` schema to map between either the "null" schema or the real schema - // Generate the inner schema for `T` We'll add some override metadata, too, so that we can mark - // this resulting schema as "optional". This is only consequential to documentation generation - // so that some of the more complex code for parsing enum schemas can correctly differentiate a - // `oneOf` schema that represents a Rust enum versus one that simply represents our "null or X" - // wrapped schema. + // Generate the inner schema for the inner type. We'll add some override metadata, too, so that + // we can mark this resulting schema as "optional". This is only consequential to documentation + // generation so that some of the more complex code for parsing enum schemas can correctly + // differentiate a `oneOf` schema that represents a Rust enum versus one that simply represents + // our "null or X" wrapped schema. let mut overrides = Metadata::default(); overrides.add_custom_attribute(CustomAttribute::flag("docs::optional")); - let mut schema = get_or_generate_schema::(gen, Some(overrides))?; + let mut schema = get_or_generate_schema(config, gen, Some(overrides))?; // Take the metadata and extensions of the original schema. // @@ -415,21 +412,6 @@ pub fn generate_one_of_schema(subschemas: &[SchemaObject]) -> SchemaObject { } } -pub fn generate_all_of_schema(subschemas: &[SchemaObject]) -> SchemaObject { - let subschemas = subschemas - .iter() - .map(|s| Schema::Object(s.clone())) - .collect::>(); - - SchemaObject { - subschemas: Some(Box::new(SubschemaValidation { - all_of: Some(subschemas), - ..Default::default() - })), - ..Default::default() - } -} - pub fn generate_tuple_schema(subschemas: &[SchemaObject]) -> SchemaObject { let subschemas = subschemas .iter() @@ -478,28 +460,29 @@ pub fn generate_internal_tagged_variant_schema( pub fn generate_root_schema() -> Result where - T: Configurable, + T: Configurable + 'static, { // Set env variable to enable generating all schemas, including platform-specific ones. std::env::set_var("VECTOR_GENERATE_SCHEMA", "true"); let schema_gen = RefCell::new(SchemaSettings::new().into_generator()); - let schema = get_or_generate_schema::(&schema_gen, Some(T::metadata()))?; + let schema = + get_or_generate_schema(&T::as_configurable_ref(), &schema_gen, Some(T::metadata()))?; + Ok(schema_gen.into_inner().into_root_schema(schema)) } -pub fn get_or_generate_schema( +pub fn get_or_generate_schema( + config: &ConfigurableRef, gen: &RefCell, overrides: Option, -) -> Result -where - T: Configurable, -{ - let (mut schema, metadata) = match T::referenceable_name() { - // When `T` has a referenceable name, try looking it up in the schema generator's definition - // list, and if it exists, create a schema reference to it. Otherwise, generate it and - // backfill it in the schema generator. +) -> Result { + let metadata = config.make_metadata(); + let (mut schema, metadata) = match config.referenceable_name() { + // When the configurable type has a referenceable name, try looking it up in the schema + // generator's definition list, and if it exists, create a schema reference to + // it. Otherwise, generate it and backfill it in the schema generator. Some(name) => { if !gen.borrow().definitions().contains_key(name) { // In order to avoid infinite recursion, we copy the approach that `schemars` takes and @@ -511,16 +494,18 @@ where .definitions_mut() .insert(name.to_string(), Schema::Bool(false)); - // We generate the schema for `T` with its own default metadata, and not the + // We generate the schema for the type with its own default metadata, and not the // override metadata passed into this method, because the override metadata might - // only be relevant to the place that `T` is being used. + // only be relevant to the place that the type is being used. // - // For example, if `T` was something for setting the logging level, one component - // that allows the logging level to be changed for that component specifically might - // want to specify a default value, whereas `T` should not have a default at all.. - // so if we applied that override metadata, we'd be unwittingly applying a default - // for all usages of `T` that didn't override the default themselves. - let schema = generate_baseline_schema::(gen, T::metadata())?; + // For example, if the type was something for setting the logging level, one + // component that allows the logging level to be changed for that component + // specifically might want to specify a default value, whereas the configurable + // should not have a default at all. So, if we applied that override metadata, we'd + // be unwittingly applying a default for all usages of the type that didn't override + // the default themselves. + let mut schema = config.generate_schema(gen)?; + apply_metadata(config, &mut schema, metadata); gen.borrow_mut() .definitions_mut() @@ -529,57 +514,43 @@ where (get_schema_ref(gen, name), None) } - // Always generate the schema directly if `T` is not referenceable. - None => (T::generate_schema(gen)?, Some(T::metadata())), + // Always generate the schema directly if the type is not referenceable. + None => (config.generate_schema(gen)?, Some(metadata)), }; // Figure out what metadata we should apply to the resulting schema. // - // If `T` was referenceable, we use its implicit metadata when generating the + // If the type was referenceable, we use its implicit metadata when generating the // "baseline" schema, because a referenceable type should always be self-contained. We then // apply the override metadata, if it exists, to the schema we got back. This allows us to // override titles, descriptions, and add additional attributes, and so on. // - // If `T` was not referenceable, we only generate its schema without trying to apply any + // If the type was not referenceable, we only generate its schema without trying to apply any // metadata. We do that because applying schema metadata enforces logic like "can't be without a - // description". The implicit metadata for `T` may lack that. + // description". The implicit metadata for the type may lack that. if let Some(overrides) = overrides.as_ref() { - T::validate_metadata(overrides)?; + config.validate_metadata(overrides)?; } - let maybe_metadata = match metadata { + match metadata { // If we generated the schema for a referenceable type, we won't need to merge its implicit // metadata into the schema we're returning _here_, so just use the override metadata if // it was given. - None => overrides, + None => { + if let Some(metadata) = overrides { + apply_metadata(config, &mut schema, metadata); + } + } // If we didn't generate the schema for a referenceable type, we'll be holding its implicit // metadata here, which we need to merge the override metadata into if it was given. If // there was no override metadata, then we just use the base by itself. Some(base) => match overrides { - None => Some(base), - Some(overrides) => Some(base.merge(overrides)), + None => apply_metadata(config, &mut schema, base), + Some(overrides) => apply_metadata(config, &mut schema, base.merge(overrides)), }, }; - if let Some(metadata) = maybe_metadata { - apply_metadata::(&mut schema, metadata); - } - - Ok(schema) -} - -pub fn generate_baseline_schema( - gen: &RefCell, - metadata: Metadata, -) -> Result -where - T: Configurable, -{ - // Generate the schema and apply its metadata. - let mut schema = T::generate_schema(gen)?; - apply_metadata::(&mut schema, metadata); - Ok(schema) } @@ -603,18 +574,19 @@ fn get_schema_ref>(gen: &RefCell, name: S) -> Sch /// /// If the schema is not a valid, string-like schema, an error variant will be returned describing /// the issue. -pub fn assert_string_schema_for_map( +pub(crate) fn assert_string_schema_for_map( + config: &ConfigurableRef, gen: &RefCell, -) -> Result<(), GenerateError> -where - K: ConfigurableString, -{ + map_type: &'static str, +) -> Result<(), GenerateError> { + let key_schema = get_or_generate_schema(config, gen, None)?; + let key_type = config.type_name(); + // We need to force the schema to be treated as transparent so that when the schema generation // finalizes the schema, we don't throw an error due to a lack of title/description. let mut key_metadata = Metadata::default(); key_metadata.set_transparent(); - let key_schema = get_or_generate_schema::(gen, None)?; let wrapped_schema = Schema::Object(key_schema); // Get a reference to the underlying schema if we're dealing with a reference, or just use what @@ -650,10 +622,7 @@ where }; if !is_string_like { - Err(GenerateError::MapKeyNotStringLike { - key_type: std::any::type_name::(), - map_type: std::any::type_name::(), - }) + Err(GenerateError::MapKeyNotStringLike { key_type, map_type }) } else { Ok(()) } diff --git a/lib/vector-config/src/stdlib.rs b/lib/vector-config/src/stdlib.rs index 71ceaacfe9bc7..e0697e582d32b 100644 --- a/lib/vector-config/src/stdlib.rs +++ b/lib/vector-config/src/stdlib.rs @@ -43,7 +43,7 @@ impl ToValue for () { // Null and boolean. impl Configurable for Option where - T: Configurable + ToValue, + T: Configurable + ToValue + 'static, { fn referenceable_name() -> Option<&'static str> { match T::referenceable_name() { @@ -67,7 +67,7 @@ where } fn generate_schema(gen: &RefCell) -> Result { - generate_optional_schema::(gen) + generate_optional_schema(&T::as_configurable_ref(), gen) } } @@ -192,7 +192,7 @@ impl_configurable_numeric!(NonZeroUsize => |v: NonZeroUsize| v.get().into()); // Arrays and maps. impl Configurable for Vec where - T: Configurable + ToValue, + T: Configurable + ToValue + 'static, { fn metadata() -> Metadata { T::metadata().convert() @@ -204,7 +204,7 @@ where } fn generate_schema(gen: &RefCell) -> Result { - generate_array_schema::(gen) + generate_array_schema(&T::as_configurable_ref(), gen) } } @@ -216,8 +216,8 @@ impl ToValue for Vec { impl Configurable for BTreeMap where - K: ConfigurableString + Ord + ToValue, - V: Configurable + ToValue, + K: ConfigurableString + Ord + ToValue + 'static, + V: Configurable + ToValue + 'static, { fn is_optional() -> bool { // A map with required fields would be... an object. So if you want that, make a struct @@ -236,9 +236,13 @@ where fn generate_schema(gen: &RefCell) -> Result { // Make sure our key type is _truly_ a string schema. - assert_string_schema_for_map::(gen)?; + assert_string_schema_for_map( + &K::as_configurable_ref(), + gen, + std::any::type_name::(), + )?; - generate_map_schema::(gen) + generate_map_schema(&V::as_configurable_ref(), gen) } } @@ -258,7 +262,7 @@ where impl Configurable for BTreeSet where - V: Configurable + ToValue + Eq + Hash, + V: Configurable + ToValue + Eq + Hash + 'static, { fn metadata() -> Metadata { Metadata::with_transparent(true) @@ -270,7 +274,7 @@ where } fn generate_schema(gen: &RefCell) -> Result { - generate_set_schema::(gen) + generate_set_schema(&V::as_configurable_ref(), gen) } } @@ -282,8 +286,8 @@ impl ToValue for BTreeSet { impl Configurable for HashMap where - K: ConfigurableString + ToValue + Hash + Eq, - V: Configurable + ToValue, + K: ConfigurableString + ToValue + Hash + Eq + 'static, + V: Configurable + ToValue + 'static, { fn is_optional() -> bool { // A map with required fields would be... an object. So if you want that, make a struct @@ -302,9 +306,13 @@ where fn generate_schema(gen: &RefCell) -> Result { // Make sure our key type is _truly_ a string schema. - assert_string_schema_for_map::(gen)?; + assert_string_schema_for_map( + &K::as_configurable_ref(), + gen, + std::any::type_name::(), + )?; - generate_map_schema::(gen) + generate_map_schema(&V::as_configurable_ref(), gen) } } @@ -324,7 +332,7 @@ where impl Configurable for HashSet where - V: Configurable + ToValue + Eq + Hash, + V: Configurable + ToValue + Eq + Hash + 'static, { fn metadata() -> Metadata { Metadata::with_transparent(true) @@ -336,7 +344,7 @@ where } fn generate_schema(gen: &RefCell) -> Result { - generate_set_schema::(gen) + generate_set_schema(&V::as_configurable_ref(), gen) } } diff --git a/src/config/id.rs b/src/config/id.rs index 4d6fa47b727c0..57c9cd33178bc 100644 --- a/src/config/id.rs +++ b/src/config/id.rs @@ -18,7 +18,7 @@ pub use vector_core::config::ComponentKey; docs::examples = "prefix-*" ))] #[derive(Clone, Debug)] -pub struct Inputs(Vec); +pub struct Inputs(Vec); impl Inputs { /// Returns `true` if no inputs are present. diff --git a/src/config/mod.rs b/src/config/mod.rs index 559f143d17a5a..6eff828c517dc 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -533,7 +533,7 @@ fn default_test_input_type() -> String { #[configurable_component] #[derive(Clone, Debug)] #[serde(deny_unknown_fields)] -pub struct TestOutput { +pub struct TestOutput { /// The transform outputs to extract events from. pub extract_from: OneOrMany, diff --git a/src/config/sink.rs b/src/config/sink.rs index 22e6e8f909879..aa25a0e614f08 100644 --- a/src/config/sink.rs +++ b/src/config/sink.rs @@ -17,7 +17,7 @@ use crate::sinks::{util::UriSerde, Healthcheck, Sinks}; #[derive(Clone, Debug)] pub struct SinkOuter where - T: Configurable + Serialize, + T: Configurable + Serialize + 'static, { #[configurable(derived)] pub inputs: Inputs, diff --git a/src/config/transform.rs b/src/config/transform.rs index f89c6fee54ef1..89cdaee33a3a2 100644 --- a/src/config/transform.rs +++ b/src/config/transform.rs @@ -22,7 +22,7 @@ use super::{id::Inputs, ComponentKey}; #[derive(Clone, Debug)] pub struct TransformOuter where - T: Configurable + Serialize, + T: Configurable + Serialize + 'static, { #[configurable(derived)] pub inputs: Inputs, diff --git a/src/serde.rs b/src/serde.rs index 9f344f74f5057..1e43bf8d1120c 100644 --- a/src/serde.rs +++ b/src/serde.rs @@ -101,7 +101,7 @@ impl Fields { #[configurable_component] #[derive(Clone, Debug, Eq, Hash, PartialEq)] #[serde(untagged)] -pub enum OneOrMany { +pub enum OneOrMany { One(T), Many(Vec), } diff --git a/src/sinks/util/buffer/compression.rs b/src/sinks/util/buffer/compression.rs index e33b47bda68f6..17215dc265c7a 100644 --- a/src/sinks/util/buffer/compression.rs +++ b/src/sinks/util/buffer/compression.rs @@ -5,8 +5,9 @@ use serde::{de, ser}; use serde_json::Value; use vector_config::{ schema::{ - apply_metadata, generate_const_string_schema, generate_enum_schema, generate_one_of_schema, - generate_struct_schema, get_or_generate_schema, SchemaGenerator, SchemaObject, + apply_base_metadata, generate_const_string_schema, generate_enum_schema, + generate_one_of_schema, generate_struct_schema, get_or_generate_schema, SchemaGenerator, + SchemaObject, }, Configurable, GenerateError, Metadata, ToValue, }; @@ -236,7 +237,7 @@ impl Configurable for Compression { const_metadata.set_title(title); } const_metadata.add_custom_attribute(CustomAttribute::kv(LOGICAL_NAME, logical_name)); - apply_metadata::<()>(&mut const_schema, const_metadata); + apply_base_metadata(&mut const_schema, const_metadata); const_schema }; @@ -262,7 +263,7 @@ impl Configurable for Compression { gzip_string_subschema, zlib_string_subschema, ]); - apply_metadata::<()>(&mut all_string_oneof_subschema, string_metadata); + apply_base_metadata(&mut all_string_oneof_subschema, string_metadata); // Next we'll create a full schema for the given algorithms. // @@ -277,7 +278,8 @@ impl Configurable for Compression { // generation, where we need to be able to generate the right enum key/value pair for the // `none` algorithm as part of the overall set of enum values declared for the `algorithm` // field in the "full" schema version. - let compression_level_schema = get_or_generate_schema::(gen, None)?; + let compression_level_schema = + get_or_generate_schema(&CompressionLevel::as_configurable_ref(), gen, None)?; let mut required = BTreeSet::new(); required.insert(ALGORITHM_NAME.to_string()); @@ -292,7 +294,7 @@ impl Configurable for Compression { let mut full_subschema = generate_struct_schema(properties, required, None); let mut full_metadata = Metadata::with_description(""); full_metadata.add_custom_attribute(CustomAttribute::flag("docs::hidden")); - apply_metadata::<()>(&mut full_subschema, full_metadata); + apply_base_metadata(&mut full_subschema, full_metadata); // Finally, we zip both schemas together. Ok(generate_one_of_schema(&[ diff --git a/src/sinks/util/service/concurrency.rs b/src/sinks/util/service/concurrency.rs index b1ea12feaf3ca..f1db75d322b74 100644 --- a/src/sinks/util/service/concurrency.rs +++ b/src/sinks/util/service/concurrency.rs @@ -4,7 +4,7 @@ use serde::Serializer; use serde_json::Value; use vector_config::{ schema::{ - apply_metadata, generate_const_string_schema, generate_number_schema, + apply_base_metadata, generate_const_string_schema, generate_number_schema, generate_one_of_schema, SchemaGenerator, SchemaObject, }, Configurable, GenerateError, Metadata, ToValue, @@ -142,7 +142,7 @@ impl Configurable for Concurrency { let mut none_metadata = Metadata::with_title("A fixed concurrency of 1."); none_metadata.set_description("Only one request can be outstanding at any given time."); none_metadata.add_custom_attribute(CustomAttribute::kv("logical_name", "None")); - apply_metadata::<()>(&mut none_schema, none_metadata); + apply_base_metadata(&mut none_schema, none_metadata); let mut adaptive_schema = generate_const_string_schema("adaptive".to_string()); let mut adaptive_metadata = Metadata::with_title( @@ -151,7 +151,7 @@ impl Configurable for Concurrency { adaptive_metadata .set_description("[arc]: https://vector.dev/docs/about/under-the-hood/networking/arc/"); adaptive_metadata.add_custom_attribute(CustomAttribute::kv("logical_name", "Adaptive")); - apply_metadata::<()>(&mut adaptive_schema, adaptive_metadata); + apply_base_metadata(&mut adaptive_schema, adaptive_metadata); let mut fixed_schema = generate_number_schema::(); let mut fixed_metadata = @@ -159,7 +159,7 @@ impl Configurable for Concurrency { fixed_metadata.set_transparent(); fixed_metadata.add_custom_attribute(CustomAttribute::kv("docs::numeric_type", "uint")); fixed_metadata.add_custom_attribute(CustomAttribute::kv("logical_name", "Fixed")); - apply_metadata::<()>(&mut fixed_schema, fixed_metadata); + apply_base_metadata(&mut fixed_schema, fixed_metadata); Ok(generate_one_of_schema(&[ none_schema,