#![cfg(feature = "alloc")]
use super::Rule;
use crate::{Head, State, Tail};
use alloc::vec::{self, Vec};
type RuleVec<Q, S> = Vec<Rule<Q, S>>;
#[derive(Clone, Debug, Default)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct Ruleset<Q = String, S = char> {
pub(crate) initial_state: Option<State<Q>>,
pub(crate) rules: RuleVec<Q, S>,
}
impl<Q, S> Ruleset<Q, S> {
pub fn new() -> Self {
Self {
initial_state: None,
rules: Vec::new(),
}
}
pub fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = Rule<Q, S>>,
{
Self {
initial_state: None,
rules: Vec::from_iter(iter),
}
}
pub fn from_state(initial_state: State<Q>) -> Self {
Self {
initial_state: Some(initial_state),
rules: Vec::new(),
}
}
pub fn with_initial_state(self, state: State<Q>) -> Self {
Self {
initial_state: Some(state),
..self
}
}
pub fn with_rules<I>(self, instructions: I) -> Self
where
I: IntoIterator<Item = Rule<Q, S>>,
{
Self {
rules: Vec::from_iter(instructions),
..self
}
}
pub fn initial_state(&self) -> Option<State<&'_ Q>> {
self.initial_state.as_ref().map(|state| state.to_ref())
}
pub const fn instructions(&self) -> &RuleVec<Q, S> {
&self.rules
}
pub fn instructions_mut(&mut self) -> &mut RuleVec<Q, S> {
&mut self.rules
}
pub fn iter(&self) -> core::slice::Iter<Rule<Q, S>> {
self.rules.iter()
}
pub fn iter_mut(&mut self) -> core::slice::IterMut<Rule<Q, S>> {
self.rules.iter_mut()
}
pub fn get(&self, State(state): State<&Q>, symbol: &S) -> Option<&Tail<Q, S>>
where
Q: PartialEq,
S: PartialEq,
{
self.iter().find_map(|i| {
if i.head().state() == state && i.head().symbol() == symbol {
Some(i.tail())
} else {
None
}
})
}
pub fn get_mut(&mut self, State(state): State<&Q>, symbol: &S) -> Option<&mut Tail<Q, S>>
where
Q: PartialEq,
S: PartialEq,
{
self.iter_mut().find_map(|i| {
if i.head().state() == state && i.head().symbol() == symbol {
Some(i.tail_mut())
} else {
None
}
})
}
pub fn get_by_head(&self, head: &Head<Q, S>) -> Option<&Tail<Q, S>>
where
Q: PartialEq,
S: PartialEq,
{
self.iter().find_map(|i| {
if i.head() == head {
Some(i.tail())
} else {
None
}
})
}
pub fn get_ref(&self, head: Head<&'_ Q, &'_ S>) -> Option<Tail<&'_ Q, &'_ S>>
where
Q: PartialEq,
S: PartialEq,
{
self.iter().find_map(|i| {
if i.head_ref() == head {
Some(i.tail_ref())
} else {
None
}
})
}
pub fn filter_by_state(&self, state: State<&Q>) -> Vec<&Rule<Q, S>>
where
Q: PartialEq,
S: PartialEq,
{
self.iter().filter(|i| *i.head() == state).collect()
}
}
impl<Q, S> AsRef<[Rule<Q, S>]> for Ruleset<Q, S> {
fn as_ref(&self) -> &[Rule<Q, S>] {
&self.rules
}
}
impl<Q, S> AsMut<[Rule<Q, S>]> for Ruleset<Q, S> {
fn as_mut(&mut self) -> &mut [Rule<Q, S>] {
&mut self.rules
}
}
impl<Q, S> core::ops::Deref for Ruleset<Q, S> {
type Target = [Rule<Q, S>];
fn deref(&self) -> &Self::Target {
&self.rules
}
}
impl<Q, S> core::ops::DerefMut for Ruleset<Q, S> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.rules
}
}
impl<Q, S> core::ops::Index<Head<Q, S>> for Ruleset<Q, S>
where
Q: PartialEq,
S: PartialEq,
{
type Output = Tail<Q, S>;
fn index(&self, index: Head<Q, S>) -> &Self::Output {
self.get_by_head(&index).unwrap()
}
}
impl<Q: Default, S> From<Vec<Rule<Q, S>>> for Ruleset<Q, S> {
fn from(instructions: Vec<Rule<Q, S>>) -> Self {
Self {
initial_state: Some(State::default()),
rules: instructions,
}
}
}
impl<Q, S> Extend<Rule<Q, S>> for Ruleset<Q, S> {
fn extend<I: IntoIterator<Item = Rule<Q, S>>>(&mut self, iter: I) {
self.rules.extend(iter)
}
}
impl<Q, S> FromIterator<Rule<Q, S>> for Ruleset<Q, S>
where
Q: Default,
{
fn from_iter<I: IntoIterator<Item = Rule<Q, S>>>(iter: I) -> Self {
Self {
initial_state: Some(State::default()),
rules: RuleVec::from_iter(iter),
}
}
}
impl<Q, S> IntoIterator for Ruleset<Q, S> {
type Item = Rule<Q, S>;
type IntoIter = vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.rules.into_iter()
}
}