use super::*;
pub trait NetdocParseable: Sized {
fn doctype_for_error() -> &'static str;
fn is_intro_item_keyword(kw: KeywordRef<'_>) -> bool;
fn from_items(input: &mut ItemStream<'_>, stop_at: stop_at!()) -> Result<Self, ErrorProblem>;
fn is_structural_keyword(kw: KeywordRef<'_>) -> Option<IsStructural>;
}
pub trait NetdocParseableFields: Sized {
type Accumulator: Sized + Debug + Send + Sync + 'static;
fn is_item_keyword(kw: KeywordRef<'_>) -> bool;
fn accumulate_item(acc: &mut Self::Accumulator, item: UnparsedItem<'_>) -> Result<(), EP>;
fn finish(acc: Self::Accumulator) -> Result<Self, EP>;
}
pub trait ItemValueParseable: Sized {
fn from_unparsed(item: UnparsedItem<'_>) -> Result<Self, ErrorProblem>;
}
pub trait ItemArgumentParseable: Sized {
fn from_args<'s>(args: &mut ArgumentStream<'s>) -> Result<Self, ArgumentError>;
}
pub trait ItemObjectParseable: Sized {
fn check_label(label: &str) -> Result<(), ErrorProblem>;
fn from_bytes(input: &[u8]) -> Result<Self, ErrorProblem>;
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[allow(clippy::exhaustive_structs)]
pub struct IsStructural;
impl<T: NormalItemArgument> ItemArgumentParseable for T {
fn from_args<'s>(args: &mut ArgumentStream<'s>) -> Result<Self, AE> {
let v = args
.next()
.ok_or(AE::Missing)?
.parse()
.map_err(|_e| AE::Missing)?;
Ok(v)
}
}
impl<T: ItemValueParseable> ItemValueParseable for Arc<T> {
fn from_unparsed(item: UnparsedItem<'_>) -> Result<Self, ErrorProblem> {
T::from_unparsed(item).map(Arc::new)
}
}
impl<T: NetdocParseable> NetdocParseable for Arc<T> {
fn doctype_for_error() -> &'static str {
T::doctype_for_error()
}
fn is_intro_item_keyword(kw: KeywordRef<'_>) -> bool {
T::is_intro_item_keyword(kw)
}
fn is_structural_keyword(kw: KeywordRef<'_>) -> Option<IsStructural> {
T::is_structural_keyword(kw)
}
fn from_items(input: &mut ItemStream<'_>, stop_at: stop_at!()) -> Result<Self, EP> {
T::from_items(input, stop_at).map(Arc::new)
}
}
impl<T: NetdocParseableFields> NetdocParseableFields for Arc<T> {
type Accumulator = T::Accumulator;
fn is_item_keyword(kw: KeywordRef<'_>) -> bool {
T::is_item_keyword(kw)
}
fn accumulate_item(acc: &mut Self::Accumulator, item: UnparsedItem<'_>) -> Result<(), EP> {
T::accumulate_item(acc, item)
}
fn finish(acc: Self::Accumulator) -> Result<Self, EP> {
T::finish(acc).map(Arc::new)
}
}
macro_rules! item_value_parseable_for_tuple {
{ $($i:literal)* } => { paste! {
impl< $( [<T$i>]: ItemArgumentParseable, )* >
ItemValueParseable for ( $( [<T$i>], )* )
{
fn from_unparsed(
#[allow(unused_mut)]
mut item: UnparsedItem<'_>,
) -> Result<Self, ErrorProblem> {
let r = ( $(
<[<T$i>] as ItemArgumentParseable>::from_args(
item.args_mut(),
).map_err(item.args().error_handler(stringify!($i)))?,
)* );
item.check_no_object()?;
Ok(r)
}
}
} }
}
item_value_parseable_for_tuple! {}
item_value_parseable_for_tuple! { 0 }
item_value_parseable_for_tuple! { 0 1 }
item_value_parseable_for_tuple! { 0 1 2 }
item_value_parseable_for_tuple! { 0 1 2 3 }
item_value_parseable_for_tuple! { 0 1 2 3 4 }
item_value_parseable_for_tuple! { 0 1 2 3 4 5 }
item_value_parseable_for_tuple! { 0 1 2 3 4 5 6 }
item_value_parseable_for_tuple! { 0 1 2 3 4 5 6 7 }
item_value_parseable_for_tuple! { 0 1 2 3 4 5 6 7 8 }
item_value_parseable_for_tuple! { 0 1 2 3 4 5 6 7 8 9 }