use facet::Facet;
#[cfg(feature = "tree-sitter-import")]
use crate::diagnostic::ImportError;
use crate::{grammar::RawRuleJson, source::SourceFile};
#[derive(Debug, Clone, Copy, Facet, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ExternalTokenOrdinal(u32);
impl ExternalTokenOrdinal {
#[cfg(feature = "tree-sitter-import")]
pub(crate) fn from_index(index: usize) -> Result<Self, ImportError> {
let value = u32::try_from(index)
.map_err(|_| ImportError::ExternalTokenOrdinalOverflow { index })?;
Ok(Self(value))
}
pub const fn get(self) -> u32 {
self.0
}
}
#[derive(Debug, Clone, Facet, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ExternalTokenName(String);
impl ExternalTokenName {
pub fn new(name: impl Into<String>) -> Self {
Self(name.into())
}
pub fn as_str(&self) -> &str {
&self.0
}
}
#[derive(Debug, Clone, Facet, PartialEq, Eq)]
pub struct ExternalTokenDecl {
ordinal: ExternalTokenOrdinal,
rule: RawRuleJson,
name: Option<ExternalTokenName>,
}
impl ExternalTokenDecl {
#[cfg(feature = "tree-sitter-import")]
fn new(ordinal: ExternalTokenOrdinal, rule: RawRuleJson) -> Self {
let name = match &rule {
RawRuleJson::Symbol { name } => Some(ExternalTokenName::new(name.clone())),
_ => None,
};
Self {
ordinal,
rule,
name,
}
}
pub const fn ordinal(&self) -> ExternalTokenOrdinal {
self.ordinal
}
pub const fn rule(&self) -> &RawRuleJson {
&self.rule
}
pub const fn name(&self) -> Option<&ExternalTokenName> {
self.name.as_ref()
}
}
#[derive(Debug, Clone, Default, Facet, PartialEq, Eq)]
#[facet(transparent)]
pub struct ExternalTokenTable(Vec<ExternalTokenDecl>);
impl ExternalTokenTable {
#[cfg(feature = "tree-sitter-import")]
pub(crate) fn from_rules(rules: &[RawRuleJson]) -> Result<Self, ImportError> {
let mut tokens = Vec::with_capacity(rules.len());
for (index, rule) in rules.iter().cloned().enumerate() {
tokens.push(ExternalTokenDecl::new(
ExternalTokenOrdinal::from_index(index)?,
rule,
));
}
Ok(Self(tokens))
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn get(&self, index: usize) -> Option<&ExternalTokenDecl> {
self.0.get(index)
}
pub fn iter(&self) -> impl Iterator<Item = &ExternalTokenDecl> {
self.0.iter()
}
}
#[derive(Debug, Clone, Facet, PartialEq, Eq)]
pub struct ScannerSource(pub String);
#[derive(Debug, Clone, Copy, Facet, PartialEq, Eq)]
#[repr(u8)]
pub enum TreeSitterScannerKind {
C,
Cpp,
}
#[derive(Debug, Clone, Facet, PartialEq, Eq)]
pub struct TreeSitterScanner {
pub kind: TreeSitterScannerKind,
pub source: SourceFile<ScannerSource>,
pub externals: ExternalTokenTable,
}