use crate::alloc_prelude::*;
#[cfg(feature = "serde")]
use crate::serde_helpers::{cow_from_string, cow_option_from_string};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct SequenceDef {
pub schema: &'static str,
pub name: &'static str,
pub increment_by: Option<&'static str>,
pub min_value: Option<&'static str>,
pub max_value: Option<&'static str>,
pub start_with: Option<&'static str>,
pub cache_size: Option<i32>,
pub cycle: Option<bool>,
}
impl SequenceDef {
#[must_use]
pub const fn new(schema: &'static str, name: &'static str) -> Self {
Self {
schema,
name,
increment_by: None,
min_value: None,
max_value: None,
start_with: None,
cache_size: None,
cycle: None,
}
}
#[must_use]
pub const fn increment_by(self, value: &'static str) -> Self {
Self {
increment_by: Some(value),
..self
}
}
#[must_use]
pub const fn min_value(self, value: &'static str) -> Self {
Self {
min_value: Some(value),
..self
}
}
#[must_use]
pub const fn max_value(self, value: &'static str) -> Self {
Self {
max_value: Some(value),
..self
}
}
#[must_use]
pub const fn start_with(self, value: &'static str) -> Self {
Self {
start_with: Some(value),
..self
}
}
#[must_use]
pub const fn cache_size(self, value: i32) -> Self {
Self {
cache_size: Some(value),
..self
}
}
#[must_use]
pub const fn cycle(self, value: bool) -> Self {
Self {
cycle: Some(value),
..self
}
}
#[must_use]
pub const fn into_sequence(self) -> Sequence {
Sequence {
schema: Cow::Borrowed(self.schema),
name: Cow::Borrowed(self.name),
increment_by: match self.increment_by {
Some(s) => Some(Cow::Borrowed(s)),
None => None,
},
min_value: match self.min_value {
Some(s) => Some(Cow::Borrowed(s)),
None => None,
},
max_value: match self.max_value {
Some(s) => Some(Cow::Borrowed(s)),
None => None,
},
start_with: match self.start_with {
Some(s) => Some(Cow::Borrowed(s)),
None => None,
},
cache_size: self.cache_size,
cycle: self.cycle,
}
}
}
impl Default for SequenceDef {
fn default() -> Self {
Self::new("public", "")
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub struct Sequence {
#[cfg_attr(feature = "serde", serde(deserialize_with = "cow_from_string"))]
pub schema: Cow<'static, str>,
#[cfg_attr(feature = "serde", serde(deserialize_with = "cow_from_string"))]
pub name: Cow<'static, str>,
#[cfg_attr(
feature = "serde",
serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "cow_option_from_string"
)
)]
pub increment_by: Option<Cow<'static, str>>,
#[cfg_attr(
feature = "serde",
serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "cow_option_from_string"
)
)]
pub min_value: Option<Cow<'static, str>>,
#[cfg_attr(
feature = "serde",
serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "cow_option_from_string"
)
)]
pub max_value: Option<Cow<'static, str>>,
#[cfg_attr(
feature = "serde",
serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "cow_option_from_string"
)
)]
pub start_with: Option<Cow<'static, str>>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub cache_size: Option<i32>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub cycle: Option<bool>,
}
impl Sequence {
#[must_use]
pub fn new(schema: impl Into<Cow<'static, str>>, name: impl Into<Cow<'static, str>>) -> Self {
Self {
schema: schema.into(),
name: name.into(),
increment_by: None,
min_value: None,
max_value: None,
start_with: None,
cache_size: None,
cycle: None,
}
}
#[inline]
#[must_use]
pub fn schema(&self) -> &str {
&self.schema
}
#[inline]
#[must_use]
pub fn name(&self) -> &str {
&self.name
}
}
impl Default for Sequence {
fn default() -> Self {
Self::new("public", "")
}
}
impl From<SequenceDef> for Sequence {
fn from(def: SequenceDef) -> Self {
def.into_sequence()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_const_sequence_def() {
const SEQ: SequenceDef = SequenceDef::new("public", "users_id_seq")
.increment_by("1")
.start_with("1")
.cycle(true);
assert_eq!(SEQ.schema, "public");
assert_eq!(SEQ.name, "users_id_seq");
assert_eq!(SEQ.increment_by, Some("1"));
assert_eq!(SEQ.cycle, Some(true));
}
#[test]
fn test_sequence_def_to_sequence() {
const DEF: SequenceDef = SequenceDef::new("public", "seq").increment_by("1");
let seq = DEF.into_sequence();
assert_eq!(seq.schema(), "public");
assert_eq!(seq.name(), "seq");
assert_eq!(seq.increment_by.as_ref().map(|s| s.as_ref()), Some("1"));
}
#[test]
fn test_sequence_with_cache() {
const SEQ: SequenceDef = SequenceDef::new("public", "seq").cache_size(100);
let seq = SEQ.into_sequence();
assert_eq!(seq.cache_size, Some(100));
}
}