use std::cell::Cell;
use std::fmt::Display;
use std::ops::Deref;
use std::rc::Rc;
use crate::BooleanJoiner;
#[derive(Debug, Clone)]
pub struct Prefix {
counter: Rc<Cell<u64>>,
prefix: String,
in_joiner_block: Option<BooleanJoiner>,
block_number: u64,
}
impl Prefix {
pub fn new(prefix: String) -> Self {
Prefix {
counter: Rc::new(0.into()),
prefix: prefix,
in_joiner_block: None,
block_number: 0,
}
}
pub fn empty() -> Self {
Self::new("".to_string())
}
pub fn in_block(&self, joiner: Option<BooleanJoiner>) -> Self {
let mut new = self.clone();
new.in_joiner_block = joiner;
new.block_number = new.get_number();
return new;
}
pub fn with(&self, token: &str) -> Self {
let mut new = self.clone();
new.prefix += token;
return new;
}
pub fn unique_reason(&self, reason: &str, group: Option<BooleanJoiner>) -> String {
let n = if group.is_some() && group == self.in_joiner_block {
self.block_number
} else {
self.get_number()
};
return format!("{reason}{n}_");
}
#[inline]
pub fn with_unique_reason(&self, reason: &str, group: Option<BooleanJoiner>) -> Self {
self.with(&self.unique_reason(reason, group))
}
pub fn get_number(&self) -> u64 {
let n = (*self.counter).get() + 1;
(*self.counter).set(n);
return n;
}
pub fn set(&self, prefix: String) -> Self {
Prefix {
counter: self.counter.clone(),
prefix: prefix,
in_joiner_block: self.in_joiner_block.clone(),
block_number: self.block_number,
}
}
}
impl Display for Prefix {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.prefix.fmt(f)
}
}
impl Deref for Prefix {
type Target = String;
fn deref(&self) -> &String {
&self.prefix
}
}