diff --git a/ion-schema/src/isl/version_based_isl/constraints/all_of.rs b/ion-schema/src/isl/version_based_isl/constraints/all_of.rs index 4c29148..5a41f4b 100644 --- a/ion-schema/src/isl/version_based_isl/constraints/all_of.rs +++ b/ion-schema/src/isl/version_based_isl/constraints/all_of.rs @@ -10,7 +10,7 @@ impl AllOf { Self { type_args } } - pub fn type_args(&self) -> &Vec> { + pub fn type_args(&self) -> &[IslTypeArgument] { &self.type_args } } diff --git a/ion-schema/src/isl/version_based_isl/constraints/any_of.rs b/ion-schema/src/isl/version_based_isl/constraints/any_of.rs index d206679..521d274 100644 --- a/ion-schema/src/isl/version_based_isl/constraints/any_of.rs +++ b/ion-schema/src/isl/version_based_isl/constraints/any_of.rs @@ -10,7 +10,7 @@ impl AnyOf { Self { type_args } } - pub fn type_args(&self) -> &Vec> { + pub fn type_args(&self) -> &[IslTypeArgument] { &self.type_args } } diff --git a/ion-schema/src/isl/version_based_isl/constraints/mod.rs b/ion-schema/src/isl/version_based_isl/constraints/mod.rs index e63a0af..31c69c6 100644 --- a/ion-schema/src/isl/version_based_isl/constraints/mod.rs +++ b/ion-schema/src/isl/version_based_isl/constraints/mod.rs @@ -21,7 +21,7 @@ pub enum IslConstraint { OneOf(OneOf), Not(Not), Type(Type), - Unknown(OpenContent), + OpenContent(OpenContent), } impl IslConstraint { @@ -51,9 +51,9 @@ impl IslConstraint { IslConstraint::Not(Not::new(isl_type_ref)) } - /// Creates an `open_content` using the field name and value referenced inside it + /// Creates open content using the field name and value referenced inside it /// Note: This open content has no effect pub fn open_content(field_name: String, field_value: Element) -> IslConstraint { - IslConstraint::Unknown(OpenContent::new(field_name, field_value)) + IslConstraint::OpenContent(OpenContent::new(field_name, field_value)) } } diff --git a/ion-schema/src/isl/version_based_isl/constraints/one_of.rs b/ion-schema/src/isl/version_based_isl/constraints/one_of.rs index 4198423..2562b19 100644 --- a/ion-schema/src/isl/version_based_isl/constraints/one_of.rs +++ b/ion-schema/src/isl/version_based_isl/constraints/one_of.rs @@ -10,7 +10,7 @@ impl OneOf { Self { type_args } } - pub fn type_args(&self) -> &Vec> { + pub fn type_args(&self) -> &[IslTypeArgument] { &self.type_args } } diff --git a/ion-schema/src/isl/version_based_isl/mod.rs b/ion-schema/src/isl/version_based_isl/mod.rs index c092a7c..4a23816 100644 --- a/ion-schema/src/isl/version_based_isl/mod.rs +++ b/ion-schema/src/isl/version_based_isl/mod.rs @@ -23,21 +23,21 @@ //! // all_of: [ //! // { type: bool } //! // ], -//! // open_content: "This is an open content!" +//! // open_content: "This is open content!" //! // } //! let isl_type: IslType = IslType::named( //! // represents the `name` of the defined type -//! "my_type_name".to_owned(), -//! vec![ +//! "my_type_name", +//! [ //! // represents the `type: int` constraint //! IslConstraint::type_constraint( //! IslTypeArgument::named("int") //! ), //! // represents `all_of` with anonymous type `{ type: bool }` constraint //! IslConstraint::all_of( -//! vec![ +//! [ //! IslTypeArgument::anonymous( -//! vec![ +//! [ //! IslConstraint::type_constraint( //! IslTypeArgument::named("bool") //! ) @@ -46,20 +46,20 @@ //! ] //! ), //! // represents some open content which will be ignored while doing validation -//! IslConstraint::open_content("open_content".to_owned(), Element::string("This is an open content!")) +//! IslConstraint::open_content("open_content".to_owned(), Element::string("This is open content!")) //! ] //! ); //! //! // create an ISL schema using above IslType -//! let isl_schema_header = IslSchemaHeader::::new(vec![], vec![]); -//! let mut isl_schema = IslSchema::new("my_schema", vec![isl_type], vec![], vec![]); +//! let isl_schema_header = IslSchemaHeader::::new([]); +//! let mut isl_schema = IslSchema::new("my_schema", [isl_type], [], []); //! isl_schema = isl_schema.with_schema_header(isl_schema_header); //! //! assert_eq!(isl_schema.types().len(), 1); -//! assert_eq!(isl_schema.types()[0].name(), &Some("my_type_name".to_owned())); +//! assert_eq!(isl_schema.types()[0].name(), Some("my_type_name")); //! assert_eq!(isl_schema.types()[0].constraints().len(), 3); //! // verify that the last constraint is actually an open content field -//! assert!(matches!(isl_schema.types()[0].constraints()[2], IslConstraint::Unknown(_))); +//! assert!(matches!(isl_schema.types()[0].constraints()[2], IslConstraint::OpenContent(_))); //! ``` //! //! ## Example usage of `version_based_isl` module to create an `IslSchema` using `IslType` for ISL 2.0: @@ -78,8 +78,8 @@ //! // } //! let isl_type: IslType = IslType::named( //! // represents the `name` of the defined type -//! "my_type_name".to_owned(), -//! vec![ +//! "my_type_name", +//! [ //! // represents the `type: int` constraint //! IslConstraint::type_constraint( //! IslTypeArgument::named("int") @@ -87,12 +87,14 @@ //! ] //! ); //! -//! let mut isl_schema_header = IslSchemaHeader::::new(vec![], vec![]); // no open content or imports are there in schema header +//! // create schema header with no open content or imports +//! let mut isl_schema_header = IslSchemaHeader::::new([]); +//! //! // Performing the following operation with ISL 1.0 schema would result in a compile time error. -//! isl_schema_header = isl_schema_header.with_user_reserved_fields(vec!["foo".to_string(), "bar".to_string()], vec![], vec![]); +//! isl_schema_header = isl_schema_header.with_user_reserved_header_fields(["foo".to_string(), "bar".to_string()]); //! //! // create an ISL schema using above IslType -//! let mut isl_schema = IslSchema::new("my_schema", vec![isl_type], vec![], vec![]); +//! let mut isl_schema = IslSchema::new("my_schema", [isl_type], [], []); //!isl_schema = isl_schema.with_schema_header(isl_schema_header); //! //! assert_eq!(isl_schema.types().len(), 1); @@ -113,7 +115,7 @@ pub trait IslVersionTrait {} pub struct IslV1_0 {} impl IslVersionTrait for IslV1_0 {} -// TODO: This can be a trait if we have get a new minor version of ISL +// TODO: This can be a trait if we get a new minor version of ISL #[derive(Debug, Clone)] pub struct IslV2_0 {} impl IslVersionTrait for IslV2_0 {} @@ -175,38 +177,59 @@ impl IslSchemaHeader { } } -impl IslSchemaHeader { - pub fn new(open_content: Vec, imports: Vec) -> Self { +impl IslSchemaHeader { + pub fn new>(imports: I) -> Self { Self { - open_content, - imports, + open_content: vec![], + imports: imports.into_iter().collect(), user_reserved_fields: UserReservedFields::default(), _version: Default::default(), } } + + pub fn with_open_content>(self, open_content: I) -> Self { + Self { + open_content: open_content.into_iter().collect(), + ..self + } + } } impl IslSchemaHeader { - pub fn new(open_content: Vec, imports: Vec) -> Self { + pub fn with_user_reserved_header_fields>( + self, + schema_header_fields: I, + ) -> Self { Self { - open_content, - imports, - user_reserved_fields: UserReservedFields::default(), - _version: Default::default(), + user_reserved_fields: UserReservedFields { + schema_header_fields: schema_header_fields.into_iter().collect(), + ..self.user_reserved_fields + }, + ..self } } - pub fn with_user_reserved_fields( + pub fn with_user_reserved_footer_fields>( self, - schema_header_fields: Vec, - schema_footer_fields: Vec, - type_fields: Vec, + schema_footer_fields: I, + ) -> Self { + Self { + user_reserved_fields: UserReservedFields { + schema_footer_fields: schema_footer_fields.into_iter().collect(), + ..self.user_reserved_fields + }, + ..self + } + } + + pub fn with_user_reserved_type_fields>( + self, + type_fields: I, ) -> Self { Self { user_reserved_fields: UserReservedFields { - schema_header_fields, - schema_footer_fields, - type_fields, + type_fields: type_fields.into_iter().collect(), + ..self.user_reserved_fields }, ..self } @@ -225,8 +248,10 @@ pub struct IslSchemaFooter { } impl IslSchemaFooter { - pub fn new(open_content: Vec) -> Self { - Self { open_content } + pub fn new>(open_content: I) -> Self { + Self { + open_content: open_content.into_iter().collect(), + } } } @@ -266,19 +291,24 @@ pub struct IslSchema { } impl IslSchema { - pub fn new>( + pub fn new< + A: AsRef, + E: IntoIterator, + I: IntoIterator, + T: IntoIterator>, + >( id: A, - types: Vec>, - inline_imports: Vec, - open_content: Vec, + types: T, + inline_imports: I, + open_content: E, ) -> Self { Self { id: id.as_ref().to_owned(), schema_header: None, schema_footer: None, - types, - inline_imported_types: inline_imports, - open_content, + types: types.into_iter().collect(), + inline_imported_types: inline_imports.into_iter().collect(), + open_content: open_content.into_iter().collect(), _version: Default::default(), } } @@ -297,8 +327,8 @@ impl IslSchema { } } - pub fn id(&self) -> String { - self.id.to_owned() + pub fn id(&self) -> &str { + &self.id } pub fn types(&self) -> &[IslType] { @@ -311,20 +341,20 @@ impl IslSchema { /// Provides top level open content for given schema /// For open content defined within type definitions use IslType#open_content() - pub fn open_content(&self) -> &Vec { + pub fn open_content(&self) -> &[Element] { &self.open_content } /// Provides the schema header value if present, /// Otherwise returns None. - pub fn schema_header(&self) -> &Option> { - &self.schema_header + pub fn schema_header(&self) -> Option<&IslSchemaHeader> { + self.schema_header.as_ref() } /// Provides the schema footer value if present, /// Otherwise returns None. - pub fn schema_footer(&self) -> &Option { - &self.schema_footer + pub fn schema_footer(&self) -> Option<&IslSchemaFooter> { + self.schema_footer.as_ref() } } @@ -363,15 +393,15 @@ impl IslType { /// Provides a name if the ISL type is named type definition /// Otherwise returns None - pub fn name(&self) -> &Option { - &self.name + pub fn name(&self) -> Option<&str> { + self.name.as_deref() } /// Provides open content that is there in the type definition pub fn open_content(&self) -> Vec<(&String, &Element)> { let mut open_contents = vec![]; for constraint in &self.constraints { - if let IslConstraint::Unknown(open_content) = constraint { + if let IslConstraint::OpenContent(open_content) = constraint { open_contents.push((open_content.field_name(), open_content.field_value())) } }