use std::collections::BTreeMap;
use std::fmt;
use qubit_datatype::DataType;
use qubit_redact::Redact;
use qubit_redact::RedactionWriter;
use qubit_redact::Redactor;
use crate::MetadataError;
use crate::MetadataResult;
use crate::schema::MetadataField;
use crate::schema::MetadataSchema;
use crate::schema::UnknownFilterFieldPolicy;
use crate::schema::UnknownMetadataFieldPolicy;
use crate::schema::internal::SchemaFields;
#[derive(Clone, PartialEq, Eq, Default)]
pub struct MetadataSchemaBuilder {
fields: BTreeMap<String, MetadataField>,
unknown_metadata_field_policy: UnknownMetadataFieldPolicy,
unknown_filter_field_policy: UnknownFilterFieldPolicy,
error: Option<MetadataError>,
}
impl Redact for MetadataSchemaBuilder {
fn write_redacted(&self, writer: &mut RedactionWriter<'_>) {
writer.record("MetadataSchemaBuilder", |fields| {
fields.nested("fields", &SchemaFields(&self.fields));
fields.unmarked("unknown_metadata_field_policy", || self.unknown_metadata_field_policy);
fields.unmarked("unknown_filter_field_policy", || self.unknown_filter_field_policy);
fields.unmarked("has_error", || self.error.is_some());
});
}
}
impl fmt::Debug for MetadataSchemaBuilder {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
let output = Redactor::strict().redact_text(self);
let text = output.text_or_marker("<redaction incomplete>");
formatter.write_str(text.as_ref())
}
}
impl MetadataSchemaBuilder {
#[inline]
#[must_use]
pub fn required(self, key: &str, data_type: DataType) -> Self {
self.declare_field(key, MetadataField::new(data_type, true))
}
#[inline]
#[must_use]
pub fn optional(self, key: &str, data_type: DataType) -> Self {
self.declare_field(key, MetadataField::new(data_type, false))
}
#[inline]
#[must_use]
pub fn replace_field(mut self, key: &str, field: MetadataField) -> Self {
let _ = self.fields.insert(key.to_string(), field);
self
}
#[inline]
#[must_use]
pub fn unknown_metadata_field_policy(mut self, policy: UnknownMetadataFieldPolicy) -> Self {
self.unknown_metadata_field_policy = policy;
self
}
#[inline]
#[must_use]
pub fn unknown_filter_field_policy(mut self, policy: UnknownFilterFieldPolicy) -> Self {
self.unknown_filter_field_policy = policy;
self
}
#[inline]
pub fn build(self) -> MetadataResult<MetadataSchema> {
if let Some(error) = self.error {
return Err(error);
}
Ok(MetadataSchema::new(
self.fields,
self.unknown_metadata_field_policy,
self.unknown_filter_field_policy,
))
}
fn declare_field(mut self, key: &str, field: MetadataField) -> Self {
if self.fields.contains_key(key) {
if self.error.is_none() {
self.error = Some(MetadataError::DuplicateSchemaField { key: key.to_string() });
}
return self;
}
let _ = self.fields.insert(key.to_string(), field);
self
}
}