use std::convert::TryFrom;
use variant_count::VariantCount;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, VariantCount)]
#[repr(u16)]
pub enum SyntaxKind {
#[doc(hidden)]
Tombstone,
TokenError,
TokenSpace,
TokenNewline,
TokenText,
TokenAt,
TokenOpenBrace,
TokenCloseBrace,
TokenOpenBracket,
TokenCloseBracket,
TokenOpenParen,
TokenCloseParen,
TokenSlash,
TokenBackslash,
TokenStar,
TokenStarStar,
TokenTilde,
TokenTildeTilde,
TokenUnderscore,
TokenColon,
TokenAdmin,
TokenMod,
NodeIcon,
NodeNewline,
NodeText,
NodeIconKey,
NodeAdmin,
NodeAdminOpen,
NodeAdminClose,
NodeMod,
NodeModOpen,
NodeModClose,
NodeEmphasis,
NodeStrikethrough,
NodeStrong,
NodeInlineContent,
NodeContent,
NodeLink,
NodeLinkContent,
NodeLinkUri,
}
impl From<SyntaxKind> for rowan::SyntaxKind {
fn from(kind: SyntaxKind) -> Self {
Self(u16::from(kind))
}
}
impl From<SyntaxKind> for u16 {
fn from(value: SyntaxKind) -> Self {
value.into_u16()
}
}
impl TryFrom<u16> for SyntaxKind {
type Error = ();
fn try_from(value: u16) -> Result<Self, Self::Error> {
if usize::from(value) < SyntaxKind::VARIANT_COUNT {
Ok(unsafe { std::mem::transmute::<u16, SyntaxKind>(value) })
} else {
Err(())
}
}
}
impl SyntaxKind {
pub const fn into_u16(self) -> u16 {
self as u16
}
pub fn is_uniline(self) -> bool {
use SyntaxKind::*;
matches!(self, TokenText | TokenOpenBracket)
}
pub fn is_token(self) -> bool {
use SyntaxKind::*;
matches!(
self,
TokenError | TokenText | TokenOpenBracket | TokenCloseBracket | TokenSlash
)
}
pub fn is_block(self) -> bool {
use SyntaxKind::*;
match self {
NodeAdmin | NodeMod => true,
n if n.is_inline() => true,
_ => false,
}
}
pub fn is_inline(self) -> bool {
use SyntaxKind::*;
matches!(
self,
NodeEmphasis | NodeIcon | NodeLink | NodeNewline | NodeText | NodeStrikethrough | NodeStrong
)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum MktLang {}
impl rowan::Language for MktLang {
type Kind = SyntaxKind;
fn kind_from_raw(raw: rowan::SyntaxKind) -> Self::Kind {
SyntaxKind::try_from(raw.0).unwrap()
}
fn kind_to_raw(kind: Self::Kind) -> rowan::SyntaxKind {
rowan::SyntaxKind(u16::from(kind))
}
}
pub type SyntaxToken = rowan::SyntaxToken<MktLang>;
pub type SyntaxNode = rowan::SyntaxNode<MktLang>;
pub type SyntaxSymbol = rowan::NodeOrToken<SyntaxNode, SyntaxToken>;
#[cfg(test)]
mod tests {
use super::SyntaxKind;
#[test]
fn test_syntax_kind_variant_count() {
assert_eq!(SyntaxKind::VARIANT_COUNT, 40);
}
}