mod utils;
pub const DEFAULT_CHARACTERS: &str =
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
pub struct LightId {
pub characters: Vec<char>,
pub min_length: usize,
status: usize,
}
impl PartialEq for LightId {
fn eq(&self, other: &Self) -> bool {
self.count() == other.count() && self.characters == other.characters
}
}
impl PartialOrd for LightId {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.count().cmp(&other.count()))
}
}
impl LightId {
pub fn new() -> Self {
LightId {
status: 0,
characters: DEFAULT_CHARACTERS.chars().collect(),
min_length: 0,
}
}
pub fn from<S: AsRef<str>>(characters: S) -> Self {
LightId {
status: 0,
characters: characters.as_ref().chars().collect(),
min_length: 0,
}
}
pub fn skip(&mut self, n: usize) -> &mut Self {
self.status = n;
self
}
pub fn last<S: AsRef<str>>(&mut self, id: S) -> &mut Self {
self.status = utils::parse_id(id.as_ref(), &self.characters);
self
}
pub fn min(&mut self, n: usize) -> &mut Self {
self.min_length = n;
self
}
pub fn chars<S: AsRef<str>>(&mut self, characters: S) -> &mut Self {
self.characters = characters.as_ref().chars().collect();
self
}
pub fn clone(&self) -> Self {
LightId {
status: self.status.clone(),
characters: self.characters.clone(),
min_length: self.min_length.clone(),
}
}
pub fn count(&self) -> usize {
return self.status;
}
pub fn decrement(&mut self) -> &mut Self {
self.decrement_by(1)
}
pub fn decrement_by(&mut self, count: usize) -> &mut Self {
if count > self.status {
self.status = 0;
} else {
self.status -= count;
}
self
}
pub fn increment(&mut self) -> &mut Self {
self.increment_by(1)
}
pub fn increment_by(&mut self, count: usize) -> &mut Self {
self.status += count;
self
}
pub fn next(&mut self) -> String {
self.status += 1;
utils::format_id(&(&self.status - 1), &self.min_length, &self.characters)
}
pub fn current(&self) -> String {
utils::format_id(&self.status, &self.min_length, &self.characters)
}
pub fn len(&self) -> usize {
if self.status == 0 {
return std::cmp::max(self.min_length, 1);
}
return std::cmp::max(
self.min_length,
self.status.ilog(self.characters.len()) as usize + 1,
);
}
pub fn nth(&self, n: usize) -> String {
utils::format_id(&n, &self.min_length, &self.characters)
}
pub fn index<S: AsRef<str>>(&self, id: S) -> usize {
utils::parse_id(id.as_ref(), &self.characters)
}
}
pub struct IdSwitcher {
source: Vec<char>,
source_min: usize,
target: Vec<char>,
target_min: usize,
}
impl IdSwitcher {
pub fn new<S: AsRef<str>>(source: S, target: S) -> Self {
IdSwitcher {
source: source.as_ref().chars().collect(),
source_min: 0,
target: target.as_ref().chars().collect(),
target_min: 0
}
}
pub fn clone (&self) -> Self {
IdSwitcher {
source: self.source.clone(),
source_min: self.source_min.clone(),
target: self.target.clone(),
target_min: self.target_min.clone(),
}
}
pub fn min_target(&mut self, n: usize) -> &mut Self {
self.target_min = n;
self
}
pub fn min_source(&mut self, n: usize) -> &mut Self {
self.source_min = n;
self
}
pub fn switch_count(&self, id: usize) -> String {
utils::format_id(&id, &self.target_min, &self.target)
}
pub fn switch<S: AsRef<str>>(&self, id: S) -> String {
self.switch_count(utils::parse_id(id.as_ref(), &self.source))
}
pub fn switch_count_reverse(&self, id: usize) -> String {
utils::format_id(&id, &self.source_min, &self.source)
}
pub fn switch_reverse<S: AsRef<str>>(&self, id: S) -> String {
self.switch_count_reverse(utils::parse_id(id.as_ref(), &self.target))
}
}