use super::{Judgement, Question};
use crate::symbols::*;
use anyhow::Result;
use nar_dev_utils::unwrap_or_return;
use narsese::lexical::Punctuation as LexicalPunctuation;
use std::fmt::{Display, Formatter, Result as FmtResult, Write};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Punctuation {
Judgement,
Question,
}
impl Punctuation {
pub const fn from_char(c: char) -> Option<Self> {
match c {
JUDGMENT_MARK => Some(Self::Judgement),
QUESTION_MARK => Some(Self::Question),
_ => None,
}
}
pub const fn to_char(&self) -> char {
use Punctuation::*;
match self {
Judgement => JUDGMENT_MARK,
Question => QUESTION_MARK,
}
}
pub fn from_lexical(lexical: LexicalPunctuation) -> Result<Self> {
let last_char = unwrap_or_return! {
?lexical.chars().next_back()
=> Err(anyhow::anyhow!("标点字符串为空"))
};
Self::from_char(last_char)
.ok_or_else(|| anyhow::anyhow!("无效的标点字符: {last_char} @ {lexical}"))
}
}
impl Display for Punctuation {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.write_char(self.to_char())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum PunctuatedSentenceRef<'r, J, Q>
where
J: Judgement,
Q: Question,
{
Judgement(&'r J),
Question(&'r Q),
}
impl<'r, J, Q> PunctuatedSentenceRef<'r, J, Q>
where
J: Judgement,
Q: Question,
{
pub const fn to_punctuation(&self) -> Punctuation {
use PunctuatedSentenceRef::*;
match self {
Judgement(..) => Punctuation::Judgement,
Question(..) => Punctuation::Question,
}
}
#[inline(always)]
pub const fn to_char(&self) -> char {
self.to_punctuation().to_char()
}
}
impl<'r, J, Q> From<PunctuatedSentenceRef<'r, J, Q>> for Punctuation
where
J: Judgement,
Q: Question,
{
fn from(value: PunctuatedSentenceRef<'r, J, Q>) -> Self {
value.to_punctuation()
}
}
impl<'r, J, Q> Display for PunctuatedSentenceRef<'r, J, Q>
where
J: Judgement,
Q: Question,
{
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
use PunctuatedSentenceRef::*;
let sentence = match self {
Judgement(sentence) => sentence.sentence_to_display(),
Question(sentence) => sentence.sentence_to_display(),
};
write!(f, "ref{:?} @ ({sentence})", self.to_char())
}
}