use crate::{Emit, Layout, Limits};
#[non_exhaustive]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
pub enum Schema {
#[default]
Core,
Json,
Failsafe,
}
#[non_exhaustive]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
pub enum DuplicateKeys {
#[default]
Error,
LastWins,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Settings {
merge_keys: bool,
yaml11_booleans: bool,
legacy_octal: bool,
sexagesimal: bool,
digit_separators: bool,
yaml11_int_forms: bool,
schema: Schema,
duplicate_keys: DuplicateKeys,
honor_version_directive: bool,
lenient_inline_colons: bool,
resolve_tagged_variant_content: bool,
limits: Limits,
emit: Emit,
}
impl Settings {
#[must_use]
pub const fn new() -> Self {
Self {
merge_keys: false,
yaml11_booleans: false,
legacy_octal: false,
sexagesimal: false,
digit_separators: false,
yaml11_int_forms: false,
schema: Schema::Core,
duplicate_keys: DuplicateKeys::Error,
honor_version_directive: false,
lenient_inline_colons: false,
resolve_tagged_variant_content: false,
limits: Limits::new(),
emit: Emit::new(),
}
}
#[must_use]
pub const fn merge_keys(mut self, on: bool) -> Self {
self.merge_keys = on;
self
}
#[must_use]
pub const fn yaml11_booleans(mut self, on: bool) -> Self {
self.yaml11_booleans = on;
self
}
#[must_use]
pub const fn legacy_octal(mut self, on: bool) -> Self {
self.legacy_octal = on;
self
}
#[must_use]
pub const fn sexagesimal(mut self, on: bool) -> Self {
self.sexagesimal = on;
self
}
#[must_use]
pub const fn digit_separators(mut self, on: bool) -> Self {
self.digit_separators = on;
self
}
#[must_use]
pub const fn yaml11_int_forms(mut self, on: bool) -> Self {
self.yaml11_int_forms = on;
self
}
#[must_use]
pub const fn schema(mut self, schema: Schema) -> Self {
self.schema = schema;
self
}
#[must_use]
pub const fn duplicate_keys(mut self, policy: DuplicateKeys) -> Self {
self.duplicate_keys = policy;
self
}
#[must_use]
pub const fn honor_version_directive(mut self, on: bool) -> Self {
self.honor_version_directive = on;
self
}
#[must_use]
pub const fn lenient_inline_colons(mut self, on: bool) -> Self {
self.lenient_inline_colons = on;
self
}
#[must_use]
pub const fn resolve_tagged_variant_content(mut self, on: bool) -> Self {
self.resolve_tagged_variant_content = on;
self
}
#[must_use]
pub const fn limits(mut self, limits: Limits) -> Self {
self.limits = limits;
self
}
#[must_use]
pub const fn max_depth(mut self, depth: usize) -> Self {
self.limits = self.limits.max_depth(depth);
self
}
#[must_use]
pub const fn emit(mut self, emit: Emit) -> Self {
self.emit = emit;
self
}
#[must_use]
pub const fn indent(mut self, spaces: usize) -> Self {
self.emit = self.emit.indent(spaces);
self
}
#[must_use]
pub const fn get_merge_keys(&self) -> bool {
self.merge_keys
}
#[must_use]
pub const fn get_yaml11_booleans(&self) -> bool {
self.yaml11_booleans
}
#[must_use]
pub const fn get_legacy_octal(&self) -> bool {
self.legacy_octal
}
#[must_use]
pub const fn get_sexagesimal(&self) -> bool {
self.sexagesimal
}
#[must_use]
pub const fn get_digit_separators(&self) -> bool {
self.digit_separators
}
#[must_use]
pub const fn get_yaml11_int_forms(&self) -> bool {
self.yaml11_int_forms
}
#[must_use]
pub const fn get_schema(&self) -> Schema {
self.schema
}
#[must_use]
pub const fn get_duplicate_keys(&self) -> DuplicateKeys {
self.duplicate_keys
}
#[must_use]
pub const fn get_honor_version_directive(&self) -> bool {
self.honor_version_directive
}
#[must_use]
pub const fn get_lenient_inline_colons(&self) -> bool {
self.lenient_inline_colons
}
#[must_use]
pub const fn get_resolve_tagged_variant_content(&self) -> bool {
self.resolve_tagged_variant_content
}
#[must_use]
pub const fn get_limits(&self) -> &Limits {
&self.limits
}
#[must_use]
pub const fn get_emit(&self) -> &Emit {
&self.emit
}
}
impl Default for Settings {
fn default() -> Self {
Self::new()
}
}
#[non_exhaustive]
#[derive(Clone, Copy, Debug)]
pub struct Compat;
impl Compat {
#[must_use]
pub const fn serde_yaml() -> Settings {
Settings::new()
.duplicate_keys(DuplicateKeys::LastWins)
.yaml11_int_forms(true)
.resolve_tagged_variant_content(true)
.emit(
Emit::new()
.indent_sequences(false)
.layout(Layout::SerdeYaml),
)
}
#[must_use]
pub const fn yaml_1_1() -> Settings {
Settings::new()
.merge_keys(true)
.yaml11_booleans(true)
.legacy_octal(true)
.sexagesimal(true)
.digit_separators(true)
.yaml11_int_forms(true)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{Layout, QuoteStyle};
#[test]
fn schema_variants_are_all_resolved() {
for s in [Schema::Core, Schema::Json, Schema::Failsafe] {
match s {
Schema::Core | Schema::Json | Schema::Failsafe => {}
}
}
}
#[test]
fn duplicate_keys_variants_are_all_handled() {
for p in [DuplicateKeys::Error, DuplicateKeys::LastWins] {
match p {
DuplicateKeys::Error | DuplicateKeys::LastWins => {}
}
}
}
#[test]
fn defaults_are_yaml_1_2() {
let s = Settings::default();
assert_eq!(s, Settings::new());
assert!(!s.get_merge_keys());
assert!(!s.get_yaml11_booleans());
assert!(!s.get_legacy_octal());
assert!(!s.get_sexagesimal());
assert!(!s.get_digit_separators());
assert!(!s.get_yaml11_int_forms());
assert_eq!(s.get_schema(), Schema::Core);
assert_eq!(s.get_duplicate_keys(), DuplicateKeys::Error);
assert!(!s.get_honor_version_directive());
assert!(!s.get_lenient_inline_colons());
assert!(!s.get_resolve_tagged_variant_content());
assert_eq!(s.get_limits(), &Limits::default());
assert_eq!(s.get_emit(), &Emit::default());
}
#[test]
fn every_setter_chains_in_const() {
const S: Settings = Settings::new()
.merge_keys(true)
.yaml11_booleans(true)
.legacy_octal(true)
.sexagesimal(true)
.digit_separators(true)
.yaml11_int_forms(true)
.schema(Schema::Failsafe)
.duplicate_keys(DuplicateKeys::LastWins)
.honor_version_directive(true)
.lenient_inline_colons(true)
.resolve_tagged_variant_content(true)
.limits(Limits::untrusted())
.max_depth(5)
.emit(Emit::new().quote_style(QuoteStyle::Double))
.indent(3);
assert!(S.get_merge_keys() && S.get_yaml11_booleans() && S.get_legacy_octal());
assert!(S.get_sexagesimal() && S.get_digit_separators() && S.get_yaml11_int_forms());
assert!(S.get_honor_version_directive() && S.get_lenient_inline_colons());
assert!(S.get_resolve_tagged_variant_content());
assert_eq!(S.get_schema(), Schema::Failsafe);
assert_eq!(S.get_duplicate_keys(), DuplicateKeys::LastWins);
assert_eq!(S.get_limits(), &Limits::untrusted().max_depth(5));
assert_eq!(
S.get_emit(),
&Emit::new().quote_style(QuoteStyle::Double).indent(3)
);
assert_eq!(Schema::default(), Schema::Core);
assert_eq!(DuplicateKeys::default(), DuplicateKeys::Error);
}
#[test]
fn presets() {
let s = Compat::serde_yaml();
assert_eq!(s.get_duplicate_keys(), DuplicateKeys::LastWins);
assert_eq!(s.get_emit().get_layout(), Layout::SerdeYaml);
assert!(!s.get_emit().get_indent_sequences());
assert!(!s.get_merge_keys() && !s.get_lenient_inline_colons());
assert!(s.get_yaml11_int_forms() && s.get_resolve_tagged_variant_content());
assert!(!s.get_yaml11_booleans() && !s.get_legacy_octal());
assert!(!s.get_sexagesimal() && !s.get_digit_separators());
let y = Compat::yaml_1_1();
assert!(y.get_merge_keys() && y.get_yaml11_booleans() && y.get_legacy_octal());
assert!(y.get_sexagesimal() && y.get_digit_separators() && y.get_yaml11_int_forms());
assert!(!y.get_lenient_inline_colons() && !y.get_resolve_tagged_variant_content());
assert_eq!(y.get_schema(), Schema::Core);
for preset in [s, y] {
assert_eq!(preset.get_limits(), &Limits::default());
}
let o = Compat::serde_yaml().duplicate_keys(DuplicateKeys::Error);
assert_eq!(o.get_duplicate_keys(), DuplicateKeys::Error);
}
}