use crate::syntax::names::{GenericParamName, ModuleAliasName, NameAtom};
use crate::syntax::non_empty::NonEmpty;
use crate::syntax::span::{Span, Spanned};
#[derive(Debug, Clone)]
pub struct Attribute {
pub name: Ident,
pub args: Vec<AttributeArg>,
pub span: Span,
}
#[derive(Debug, Clone)]
pub enum AttributeArg {
Path {
segments: NonEmpty<Ident>,
span: Span,
},
RangeStep { step: u64, span: Span },
Group { elements: Vec<Self>, span: Span },
}
impl AttributeArg {
#[must_use]
pub const fn span(&self) -> Span {
match self {
Self::Path { span, .. } | Self::RangeStep { span, .. } | Self::Group { span, .. } => {
*span
}
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Visibility {
Private,
Public,
}
impl Visibility {
#[must_use]
pub const fn is_public(self) -> bool {
matches!(self, Self::Public)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BindableVisibility {
Private,
Public,
PublicBind,
}
impl BindableVisibility {
#[must_use]
pub const fn is_public(self) -> bool {
matches!(self, Self::Public | Self::PublicBind)
}
#[must_use]
pub const fn is_bindable(self) -> bool {
matches!(self, Self::PublicBind)
}
}
impl From<Visibility> for BindableVisibility {
fn from(visibility: Visibility) -> Self {
match visibility {
Visibility::Private => Self::Private,
Visibility::Public => Self::Public,
}
}
}
#[derive(Debug, Clone)]
pub enum ImportKind {
Selective(Vec<ImportItem>),
Module {
alias: Option<Spanned<ModuleAliasName>>,
},
}
#[derive(Debug, Clone)]
pub struct ModulePath {
pub segments: NonEmpty<Ident>,
pub span: Span,
}
impl ModulePath {
#[must_use]
pub const fn span(&self) -> Span {
self.span
}
#[must_use]
pub fn segments(&self) -> &[Ident] {
self.segments.as_slice()
}
#[must_use]
pub const fn len(&self) -> usize {
self.segments.len()
}
#[must_use]
pub const fn is_empty(&self) -> bool {
false
}
#[must_use]
pub const fn is_bare(&self) -> bool {
self.segments.len() == 1
}
#[must_use]
pub fn display_path(&self) -> String {
self.segments
.iter()
.map(|s| s.name.as_str())
.collect::<Vec<_>>()
.join(".")
}
#[must_use]
pub fn leaf(&self) -> &Ident {
self.segments.last()
}
#[must_use]
pub fn split_last(&self) -> (&[Ident], &Ident) {
let (leaf, qualifier) = self.segments.split_last();
(qualifier, leaf)
}
#[must_use]
pub fn qualifier_segments(&self) -> &[Ident] {
self.split_last().0
}
#[must_use]
pub fn qualifier_and_leaf(&self) -> Option<(&[Ident], &Ident)> {
let (qualifier, leaf) = self.split_last();
(!qualifier.is_empty()).then_some((qualifier, leaf))
}
}
#[derive(Debug, Clone)]
pub struct ImportItem {
pub attributes: Vec<Attribute>,
pub is_pub: bool,
pub namespace: ImportItemNamespace,
pub name: Ident,
pub alias: Option<Ident>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ImportItemNamespace {
Default,
Type,
}
impl ImportItem {
#[must_use]
pub fn local_name(&self) -> &str {
self.alias
.as_ref()
.map_or(self.name.name.as_str(), |a| a.name.as_str())
}
#[must_use]
pub fn local_span(&self) -> Span {
self.alias.as_ref().map_or(self.name.span, |a| a.span)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Ident {
pub name: NameAtom,
pub span: Span,
}
impl Ident {
#[must_use]
pub fn into_spanned<T: From<NameAtom>>(self) -> Spanned<T> {
Spanned::new(T::from(self.name), self.span)
}
#[must_use]
pub fn as_generic_param_name(&self) -> GenericParamName {
GenericParamName::new(&self.name)
}
}