use super::BoxSlice;
use crate::token::CommentKind;
use solar_interface::{Ident, Span, Symbol};
use std::fmt;
#[derive(Debug)]
pub struct DocComment<'ast> {
pub kind: CommentKind,
pub span: Span,
pub symbol: Symbol,
pub natspec: BoxSlice<'ast, NatSpecItem>,
}
impl<'ast> DocComment<'ast> {
pub fn natspec_content<'a>(&self, item: &'a NatSpecItem) -> &'a str {
item.content()
}
}
#[derive(Clone, Copy, Debug)]
pub struct NatSpecItem {
pub kind: NatSpecKind,
pub span: Span,
pub symbol: Symbol,
pub content_start: u32,
pub content_end: u32,
}
impl NatSpecItem {
pub fn content_range(&self) -> std::ops::Range<usize> {
self.content_start as usize..self.content_end as usize
}
pub fn content(&self) -> &str {
&self.symbol.as_str()[self.content_range()]
}
}
impl fmt::Display for NatSpecItem {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let content = self.content();
match self.kind {
NatSpecKind::Title => write!(f, "@title {content}"),
NatSpecKind::Author => write!(f, "@author {content}"),
NatSpecKind::Notice => write!(f, "@notice {content}"),
NatSpecKind::Dev => write!(f, "@dev {content}"),
NatSpecKind::Param { name } => write!(f, "@param {} {content}", name.name),
NatSpecKind::Return { name: Some(name) } => {
write!(f, "@return {} {content}", name.name)
}
NatSpecKind::Return { name: None } => write!(f, "@return {content}"),
NatSpecKind::Inheritdoc { contract } => {
write!(f, "@inheritdoc {} {content}", contract.name)
}
NatSpecKind::Custom { name } => write!(f, "@custom:{} {content}", name.name),
NatSpecKind::Internal { tag } => write!(f, "@{} {content}", tag.name),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum NatSpecKind {
Title,
Author,
Notice,
Dev,
Param { name: Ident },
Return { name: Option<Ident> },
Inheritdoc { contract: Ident },
Custom { name: Ident },
Internal { tag: Ident },
}
pub const NATSPEC_INTERNAL_TAGS: &[&str] = &["solidity", "src", "use-src", "ast-id"];