use crate::model::identifiers::{Identifier, IdentifierReference};
use std::{
collections::HashSet,
fmt::{Debug, Display},
hash::Hash,
ops::Range,
};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[macro_use]
mod macros;
pub trait HasBody {
type Body;
fn body(&self) -> &Self::Body;
fn body_mut(&mut self) -> &mut Self::Body;
fn set_body(&mut self, body: Self::Body);
}
pub trait HasName {
fn name(&self) -> &Identifier;
fn set_name(&mut self, name: Identifier);
}
pub trait HasNameReference {
fn name_reference(&self) -> &IdentifierReference;
fn set_name_reference(&mut self, name: IdentifierReference);
}
pub trait Namespace {
type Member: HasName;
fn has_members(&self) -> bool;
fn member_count(&self) -> usize;
fn contains_member(&self, name: &Identifier) -> bool;
fn member(&self, name: &Identifier) -> Option<&Self::Member>;
fn members(&self) -> impl Iterator<Item = &Self::Member>;
fn members_mut(&mut self) -> impl Iterator<Item = &mut Self::Member>;
fn member_names(&self) -> impl Iterator<Item = &Identifier>;
fn add_to_members(&mut self, value: Self::Member) -> Option<Self::Member>;
fn extend_members<I>(&mut self, extension: I)
where
I: IntoIterator<Item = Self::Member>;
}
pub trait HasOptionalBody {
type Body;
fn has_body(&self) -> bool {
self.body().is_some()
}
fn body(&self) -> Option<&Self::Body>;
fn body_mut(&mut self) -> Option<&mut Self::Body>;
fn set_body(&mut self, body: Self::Body);
fn unset_body(&mut self);
}
pub trait HasSourceSpan {
fn with_source_span(self, ts_span: Span) -> Self;
fn has_source_span(&self) -> bool {
self.source_span().is_some()
}
fn source_span(&self) -> Option<&Span>;
fn set_source_span(&mut self, span: Span);
fn unset_source_span(&mut self);
}
pub trait References {
#[allow(unused_variables)]
fn referenced_types<'a>(&'a self, names: &mut HashSet<&'a IdentifierReference>) {}
#[allow(unused_variables)]
fn referenced_annotations<'a>(&'a self, names: &mut HashSet<&'a IdentifierReference>) {}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct Span {
start: SpanPosition,
end: SpanPosition,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct SpanPosition {
byte: usize,
line: usize,
column: usize,
}
#[cfg(feature = "tree-sitter")]
impl From<&tree_sitter::Node<'_>> for Span {
fn from(node: &tree_sitter::Node<'_>) -> Self {
Self {
start: SpanPosition::from(node.start_position(), node.start_byte()),
end: SpanPosition::from(node.end_position(), node.end_byte()),
}
}
}
#[cfg(feature = "tree-sitter")]
impl From<tree_sitter::Node<'_>> for Span {
fn from(node: tree_sitter::Node<'_>) -> Self {
Self::from(&node)
}
}
impl From<&Span> for sdml_errors::Span {
fn from(value: &Span) -> Self {
value.byte_range()
}
}
impl From<Span> for sdml_errors::Span {
fn from(value: Span) -> Self {
value.byte_range()
}
}
impl Display for Span {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}..{}", self.start.byte, self.end.byte)
}
}
impl Span {
#[inline(always)]
pub fn new(start: SpanPosition, end: SpanPosition) -> Self {
assert!(start.byte <= end.byte);
assert!(start.line <= end.line);
assert!(start.column <= end.column || end.line > start.line);
Self { start, end }
}
#[inline(always)]
pub fn start(&self) -> SpanPosition {
self.start
}
#[inline(always)]
pub fn end(&self) -> SpanPosition {
self.end
}
#[inline(always)]
pub fn byte_range(&self) -> Range<usize> {
self.start.byte..self.end.byte
}
}
impl SpanPosition {
#[inline(always)]
pub fn new(byte: usize, line: usize, column: usize) -> Self {
Self { byte, line, column }
}
#[cfg(feature = "tree-sitter")]
pub fn from(node_point: tree_sitter::Point, byte: usize) -> Self {
Self::new(byte, node_point.row + 1, node_point.column + 1)
}
pub const fn byte(&self) -> usize {
self.byte
}
pub const fn line(&self) -> usize {
self.line
}
pub const fn column(&self) -> usize {
self.column
}
}
pub mod annotations;
pub mod check;
pub mod constraints;
pub mod definitions;
pub mod identifiers;
pub mod members;
pub mod modules;
pub mod values;
pub mod walk;