use core::fmt;
use std::collections::HashSet;
#[derive(Debug, Clone)]
pub struct Options {
options: HashSet<String>,
lastpos: u64,
messages: Vec<String>,
source: String,
}
impl Options {
pub fn new(source: String) -> Self {
Self {
options: HashSet::new(),
lastpos: 0,
messages: vec![],
source,
}
}
pub fn message(mut self, msg: impl AsRef<str>) -> Self {
self.messages.push(msg.as_ref().to_string());
self
}
pub fn pos(mut self, pos: u64) -> Self {
if pos > self.lastpos {
self.lastpos = pos;
}
self
}
pub fn merge(mut self, other: Options) -> Self {
for i in other.options {
self = self.add_str(i);
}
self
}
pub fn add(mut self, value: char) -> Self {
self.options.insert(value.to_string());
self
}
pub fn add_str(mut self, value: impl AsRef<str>) -> Self {
self.options.insert(value.as_ref().to_string());
self
}
}
impl fmt::Display for Options {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "{}", self.source)?;
writeln!(f, "{}^", " ".repeat(self.lastpos as usize))?;
if !self.options.is_empty() {
writeln!(f, "An error occurred: unexpected character.")?;
write!(f, "Expected any of: [")?;
for (index, i) in self.options.iter().enumerate() {
write!(f, "{}", i)?;
if index != self.options.len() - 1 {
write!(f, ", ")?;
}
}
writeln!(f, "]")?;
writeln!(f)?;
}
for i in self.messages.iter() {
writeln!(f, "{}", i)?;
}
Ok(())
}
}