use std::{fmt::Display, str::FromStr};
use serde::{Deserialize, Serialize};
use crate::error::DeltaSharingError;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "camelCase")]
pub struct Share {
name: String,
id: Option<String>,
}
impl Share {
pub fn new<S: Into<String>>(name: S, id: Option<S>) -> Self {
Self {
name: name.into(),
id: id.map(Into::into),
}
}
pub fn name(&self) -> &str {
self.name.as_ref()
}
pub fn id(&self) -> Option<&str> {
self.id.as_deref()
}
}
impl Display for Share {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.name())
}
}
impl FromStr for Share {
type Err = DeltaSharingError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Share::new(s, None))
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "camelCase")]
pub struct Schema {
share: String,
name: String,
}
impl Schema {
pub fn new(share_name: impl Into<String>, schema_name: impl Into<String>) -> Self {
Self {
share: share_name.into(),
name: schema_name.into(),
}
}
pub fn share_name(&self) -> &str {
self.share.as_ref()
}
pub fn name(&self) -> &str {
self.name.as_ref()
}
}
impl Display for Schema {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}.{}", self.share_name(), self.name())
}
}
impl FromStr for Schema {
type Err = DeltaSharingError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let parts = s.split('.').collect::<Vec<_>>();
if parts.len() == 2 {
Ok(Schema::new(parts[0], parts[1]))
} else {
Err(DeltaSharingError::parse_securable(
"Schema must be of the form <share>.<schema>",
))
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "camelCase")]
pub struct Table {
name: String,
schema: String,
share: String,
share_id: Option<String>,
id: Option<String>,
}
impl Table {
pub fn new(
share_name: impl Into<String>,
schema_name: impl Into<String>,
table_name: impl Into<String>,
share_id: Option<String>,
table_id: Option<String>,
) -> Self {
Self {
name: table_name.into(),
schema: schema_name.into(),
share: share_name.into(),
share_id,
id: table_id,
}
}
pub fn share_name(&self) -> &str {
self.share.as_ref()
}
pub fn share_id(&self) -> Option<&str> {
self.share_id.as_deref()
}
pub fn schema_name(&self) -> &str {
self.schema.as_ref()
}
pub fn name(&self) -> &str {
self.name.as_ref()
}
pub fn id(&self) -> Option<&str> {
self.id.as_deref()
}
}
impl Display for Table {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}.{}.{}",
self.share_name(),
self.schema_name(),
self.name()
)
}
}
impl FromStr for Table {
type Err = DeltaSharingError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let parts = s.split('.').collect::<Vec<_>>();
if parts.len() == 3 {
Ok(Table::new(parts[0], parts[1], parts[2], None, None))
} else {
Err(DeltaSharingError::parse_securable(
"Table must be of the form <share>.<schema>.<table>",
))
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn display_share() {
let share = Share::new("share", Some("id"));
assert_eq!(format!("{}", share), "share");
}
#[test]
fn parse_share() {
let share = "share".parse::<Share>().unwrap();
assert_eq!(share, Share::new("share", None));
}
#[test]
fn display_schema() {
let schema = Schema::new("share", "schema");
assert_eq!(format!("{}", schema), "share.schema");
}
#[test]
fn parse_schema() {
let schema = "share.schema".parse::<Schema>().unwrap();
assert_eq!(schema, Schema::new("share", "schema"));
}
#[test]
fn display_table() {
let table = Table::new("share", "schema", "table", None, None);
assert_eq!(format!("{}", table), "share.schema.table");
}
#[test]
fn parse_table() {
let table = "share.schema.table".parse::<Table>().unwrap();
assert_eq!(table, Table::new("share", "schema", "table", None, None));
}
}