use crate::quotes::{QUOTES, read_reference};
use std::fmt;
use std::hash::{Hash, Hasher};
#[derive(Debug, Clone, Default)]
pub struct SyntaxReference {
pub value: String,
pub raw: Option<String>,
}
impl SyntaxReference {
pub fn new(value: impl Into<String>) -> Self {
Self {
value: value.into(),
raw: None,
}
}
pub fn with_raw(value: impl Into<String>, raw: impl Into<String>) -> Self {
Self {
value: value.into(),
raw: Some(raw.into()),
}
}
pub fn as_str(&self) -> &str {
&self.value
}
pub fn quote(&self) -> Option<char> {
self.raw.as_deref().and_then(reference_quote)
}
}
impl PartialEq for SyntaxReference {
fn eq(&self, other: &Self) -> bool {
self.value == other.value
}
}
impl Eq for SyntaxReference {}
impl Hash for SyntaxReference {
fn hash<H: Hasher>(&self, state: &mut H) {
self.value.hash(state);
}
}
impl PartialOrd for SyntaxReference {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for SyntaxReference {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.value.cmp(&other.value)
}
}
impl PartialEq<str> for SyntaxReference {
fn eq(&self, other: &str) -> bool {
self.value == other
}
}
impl PartialEq<&str> for SyntaxReference {
fn eq(&self, other: &&str) -> bool {
self.value == *other
}
}
impl PartialEq<String> for SyntaxReference {
fn eq(&self, other: &String) -> bool {
&self.value == other
}
}
impl fmt::Display for SyntaxReference {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.value)
}
}
impl From<String> for SyntaxReference {
fn from(value: String) -> Self {
Self::new(value)
}
}
impl From<&str> for SyntaxReference {
fn from(value: &str) -> Self {
Self::new(value)
}
}
impl From<SyntaxReference> for String {
fn from(reference: SyntaxReference) -> Self {
reference.value
}
}
pub fn reference_quote(raw: &str) -> Option<char> {
let first = *raw.as_bytes().first()?;
if !QUOTES.contains(&first) {
return None;
}
let reading = read_reference(raw)?;
(reading.length == raw.len()).then_some(first as char)
}