use std::{
fmt::{self, Debug, Display},
hash::Hash,
};
pub trait Ident:
Debug + Clone + PartialEq + Eq + PartialOrd + Ord + Hash + Send + Sync + 'static
{
fn is_none(&self) -> bool;
fn is_end_of_path(&self) -> bool {
false
}
fn span(&self) -> Option<laburnum::Span> {
None
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct StringIdent(String);
impl StringIdent {
pub fn new(s: impl Into<String>) -> Self {
StringIdent(s.into())
}
pub fn as_str(&self) -> &str {
&self.0
}
}
impl Ident for StringIdent {
fn is_none(&self) -> bool {
false
}
fn span(&self) -> Option<laburnum::Span> {
None
}
}
impl Display for StringIdent {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl From<String> for StringIdent {
fn from(s: String) -> Self {
StringIdent(s)
}
}
impl From<&str> for StringIdent {
fn from(s: &str) -> Self {
StringIdent(s.to_string())
}
}
impl AsRef<str> for StringIdent {
fn as_ref(&self) -> &str {
&self.0
}
}
impl Ident for laburnum::Ident {
fn is_none(&self) -> bool {
self.0 == 0
}
fn span(&self) -> Option<laburnum::Span> {
None
}
}
impl Ident for laburnum::Spanned<laburnum::Ident> {
fn is_none(&self) -> bool {
self.0.is_none()
}
fn is_end_of_path(&self) -> bool {
false
}
fn span(&self) -> Option<laburnum::Span> {
Some(self.1)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn string_ident_new() {
let ident = StringIdent::new("foo");
assert_eq!(ident.as_str(), "foo");
}
#[test]
fn string_ident_from_string() {
let ident = StringIdent::from(String::from("bar"));
assert_eq!(ident.as_str(), "bar");
}
#[test]
fn string_ident_from_str() {
let ident = StringIdent::from("baz");
assert_eq!(ident.as_str(), "baz");
}
#[test]
fn string_ident_as_str() {
let ident = StringIdent::new("hello");
assert_eq!(ident.as_str(), "hello");
}
#[test]
fn string_ident_display() {
let ident = StringIdent::new("world");
assert_eq!(format!("{}", ident), "world");
}
#[test]
fn string_ident_is_none_returns_false() {
let ident = StringIdent::new("anything");
assert!(!ident.is_none());
}
#[test]
fn string_ident_equality() {
let a = StringIdent::new("same");
let b = StringIdent::new("same");
assert_eq!(a, b);
}
#[test]
fn string_ident_ordering() {
let a = StringIdent::new("aaa");
let b = StringIdent::new("bbb");
assert!(a < b);
}
#[test]
fn laburnum_ident_is_none_when_zero() {
let zero = laburnum::Ident(0);
assert!(zero.is_none());
let nonzero = laburnum::Ident(1);
assert!(!nonzero.is_none());
}
}