emmylua_parser/syntax/node/doc/
description.rs

1use crate::{LuaAstNode, LuaDocDetailToken, LuaSyntaxKind, LuaSyntaxNode, LuaTokenKind};
2
3#[allow(unused)]
4pub trait LuaDocDescriptionOwner: LuaAstNode {
5    fn get_description(&self) -> Option<LuaDocDescription> {
6        self.child()
7    }
8}
9
10#[allow(unused)]
11pub trait LuaDocDetailOwner: LuaAstNode {
12    fn get_detail(&self) -> Option<LuaDocDetailToken> {
13        self.token()
14    }
15
16    fn get_detail_text(&self) -> Option<String> {
17        self.get_detail().map(|it| it.get_detail().to_string())
18    }
19}
20
21#[derive(Debug, Clone, PartialEq, Eq, Hash)]
22pub struct LuaDocDescription {
23    syntax: LuaSyntaxNode,
24}
25
26impl LuaAstNode for LuaDocDescription {
27    fn syntax(&self) -> &LuaSyntaxNode {
28        &self.syntax
29    }
30
31    fn can_cast(kind: LuaSyntaxKind) -> bool
32    where
33        Self: Sized,
34    {
35        kind == LuaSyntaxKind::DocDescription
36    }
37
38    fn cast(syntax: LuaSyntaxNode) -> Option<Self>
39    where
40        Self: Sized,
41    {
42        if syntax.kind() == LuaSyntaxKind::DocDescription.into() {
43            Some(Self { syntax })
44        } else {
45            None
46        }
47    }
48}
49
50impl LuaDocDetailOwner for LuaDocDescription {}
51
52impl LuaDocDescription {
53    pub fn get_description_text(&self) -> String {
54        let mut text = String::new();
55        for token in self
56            .syntax()
57            .children_with_tokens()
58            .filter_map(|it| it.into_token())
59        {
60            match token.kind().into() {
61                LuaTokenKind::TkDocDetail => {
62                    text.push_str(token.text());
63                }
64                LuaTokenKind::TkEndOfLine => {
65                    text.push('\n');
66                }
67                LuaTokenKind::TkNormalStart | LuaTokenKind::TkDocContinue => {
68                    let mut white_space_count = 0;
69                    let mut start_text_chars = token.text().chars();
70                    while let Some(c) = start_text_chars.next() {
71                        if c == ' ' {
72                            white_space_count += 1;
73                        } else if c == '\t' {
74                            white_space_count += 4;
75                        }
76                    }
77
78                    if white_space_count > 0 {
79                        let white_space = " ".repeat(white_space_count);
80                        text.push_str(&white_space);
81                    }
82                }
83                _ => {}
84            }
85        }
86
87        text
88    }
89}