#![forbid(unsafe_code)]
#![doc = include_str!("../README.md")]
use use_db_name::{CollectionName, ConstraintName, DatabaseName, IndexName, SchemaName, TableName};
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct SchemaRef {
database: Option<DatabaseName>,
schema: SchemaName,
}
impl SchemaRef {
#[must_use]
pub const fn new(schema: SchemaName) -> Self {
Self {
database: None,
schema,
}
}
#[must_use]
pub fn with_database(mut self, database: DatabaseName) -> Self {
self.database = Some(database);
self
}
#[must_use]
pub const fn database(&self) -> Option<&DatabaseName> {
self.database.as_ref()
}
#[must_use]
pub const fn schema(&self) -> &SchemaName {
&self.schema
}
}
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum SchemaObject {
Table(TableName),
Collection(CollectionName),
Index(IndexName),
Constraint(ConstraintName),
Other(String),
}
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct SchemaVersion(String);
impl SchemaVersion {
#[must_use]
pub fn new(version: impl Into<String>) -> Self {
Self(version.into())
}
#[must_use]
pub fn as_str(&self) -> &str {
&self.0
}
}
#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct SchemaNamespace {
schemas: Vec<SchemaName>,
}
impl SchemaNamespace {
#[must_use]
pub const fn new(schemas: Vec<SchemaName>) -> Self {
Self { schemas }
}
#[must_use]
pub fn schemas(&self) -> &[SchemaName] {
&self.schemas
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.schemas.is_empty()
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SchemaMetadata {
reference: SchemaRef,
version: Option<SchemaVersion>,
objects: Vec<SchemaObject>,
}
impl SchemaMetadata {
#[must_use]
pub const fn new(reference: SchemaRef) -> Self {
Self {
reference,
version: None,
objects: Vec::new(),
}
}
#[must_use]
pub fn with_version(mut self, version: SchemaVersion) -> Self {
self.version = Some(version);
self
}
#[must_use]
pub fn with_objects(mut self, objects: Vec<SchemaObject>) -> Self {
self.objects = objects;
self
}
#[must_use]
pub const fn reference(&self) -> &SchemaRef {
&self.reference
}
#[must_use]
pub const fn version(&self) -> Option<&SchemaVersion> {
self.version.as_ref()
}
#[must_use]
pub fn objects(&self) -> &[SchemaObject] {
&self.objects
}
}
#[cfg(test)]
mod tests {
use super::{SchemaMetadata, SchemaNamespace, SchemaObject, SchemaRef, SchemaVersion};
use use_db_name::{DatabaseName, SchemaName, TableName};
#[test]
fn stores_schema_metadata() -> Result<(), Box<dyn std::error::Error>> {
let schema = SchemaName::new("public")?;
let reference = SchemaRef::new(schema.clone()).with_database(DatabaseName::new("app")?);
let metadata = SchemaMetadata::new(reference).with_version(SchemaVersion::new("1"));
let namespace = SchemaNamespace::new(vec![schema]);
assert_eq!(
metadata.reference().database().expect("database").as_str(),
"app"
);
assert_eq!(metadata.version().expect("version").as_str(), "1");
assert!(!namespace.is_empty());
assert_eq!(
SchemaObject::Table(TableName::new("users")?),
SchemaObject::Table(TableName::new("users")?)
);
Ok(())
}
}