lemmy_help/lexer/
token.rs

1use std::fmt::Display;
2
3#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4pub enum Member {
5    Literal(String),
6    Ident(String),
7}
8
9impl Display for Member {
10    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
11        match self {
12            Self::Literal(lit) => f.write_str(&format!(
13                r#""{}""#,
14                lit.trim_start_matches('"').trim_end_matches('"')
15            )),
16            Self::Ident(ident) => f.write_str(ident),
17        }
18    }
19}
20
21#[derive(Debug, Clone, PartialEq, Eq, Hash)]
22pub enum TagType {
23    /// ```lua
24    /// ---@toc <name>
25    /// ```
26    Toc(String),
27    /// ```lua
28    /// ---@mod <name> [desc]
29    /// ```
30    Module(String, Option<String>),
31    /// ```lua
32    /// ---@divider <char>
33    /// ```
34    Divider(char),
35    /// ```lua
36    /// function one.two() end
37    /// one.two = function() end
38    /// ```
39    Func(String, Op),
40    /// ```lua
41    /// one = 1
42    /// one.two = 12
43    /// ```
44    Expr(String, Op),
45    /// ```lua
46    /// ---@export <module>
47    /// or
48    /// return <module>\eof
49    /// ```
50    Export(String),
51    /// ```lua
52    /// ---@brief [[
53    /// ```
54    BriefStart,
55    /// ```lua
56    /// ---@brief ]]
57    /// ```
58    BriefEnd,
59    /// ```lua
60    /// ---@param <name[?]> <type[|type...]> [description]
61    /// ```
62    Param(Name, Ty, Option<String>),
63    /// ```lua
64    /// ---@return <type> [<name> [comment] | [name] #<comment>]
65    /// ```
66    Return(Ty, Option<String>, Option<String>),
67    /// ```lua
68    /// ---@class <name>[: <parent>]
69    /// ```
70    Class(String, Option<String>),
71    /// ```lua
72    /// ---@field [public|private|protected] <name[?]> <type> [description]
73    /// ```
74    Field(Scope, Name, Ty, Option<String>),
75    /// ```lua
76    /// -- Simple Alias
77    /// ---@alias <name> <type>
78    ///
79    /// -- Enum alias
80    /// ---@alias <name>
81    /// ```
82    Alias(String, Option<Ty>),
83    /// ```lua
84    /// ---| '<literal>' [# description]
85    ///
86    /// -- or
87    ///
88    /// ---| `<ident>` [# description]
89    /// ```
90    Variant(Member, Option<String>),
91    /// ```lua
92    /// ---@type <type> [desc]
93    /// ```
94    Type(Ty, Option<String>),
95    /// ```lua
96    /// ---@tag <name>
97    /// ```
98    Tag(String),
99    /// ```lua
100    /// ---@see <name>
101    /// ```
102    See(String),
103    /// ```lua
104    /// ---@usage [lang] `<code>`
105    /// ```
106    Usage(Option<String>, String),
107    /// ```lua
108    /// ---@usage [lang] [[
109    /// ```
110    UsageStart(Option<String>),
111    /// ```lua
112    /// ---@usage ]]
113    /// ```
114    UsageEnd,
115    /// ```lua
116    /// ---TEXT
117    /// ```
118    Comment(String),
119    /// Text nodes which are not needed
120    Skip,
121}
122
123#[derive(Debug, Clone, PartialEq, Eq, Hash)]
124pub enum Op {
125    Deep(Vec<Op>),
126    Dot(String),
127    Colon(String),
128}
129
130impl Display for Op {
131    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
132        match self {
133            Self::Deep(mixed) => {
134                for mix in mixed {
135                    mix.fmt(f)?;
136                }
137                Ok(())
138            }
139            Self::Dot(dot) => {
140                f.write_str(".")?;
141                f.write_str(dot)
142            }
143            Self::Colon(colon) => {
144                f.write_str(":")?;
145                f.write_str(colon)
146            }
147        }
148    }
149}
150
151#[derive(Debug, Clone, PartialEq, Eq, Hash)]
152pub enum Scope {
153    Public,
154    Private,
155    Protected,
156    Package,
157}
158
159#[derive(Debug, Clone, PartialEq, Eq, Hash)]
160pub enum Name {
161    Req(String),
162    Opt(String),
163}
164
165impl Display for Name {
166    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
167        match self {
168            Self::Req(n) => f.write_str(n),
169            Self::Opt(n) => {
170                f.write_str(n)?;
171                f.write_str("?")
172            }
173        }
174    }
175}
176
177// Source: https://github.com/sumneko/lua-language-server/wiki/Annotations#documenting-types
178#[derive(Debug, Clone, PartialEq, Eq, Hash)]
179pub enum Ty {
180    Nil,
181    Any,
182    Unknown,
183    Boolean,
184    String,
185    Number,
186    Integer,
187    Function,
188    Thread,
189    Userdata,
190    Lightuserdata,
191    Ref(String),
192    Member(Member),
193    Array(Box<Ty>),
194    Table(Option<(Box<Ty>, Box<Ty>)>),
195    Fun(Vec<(Name, Ty)>, Option<Vec<Ty>>),
196    Dict(Vec<(Name, Ty)>),
197    Union(Box<Ty>, Box<Ty>),
198}
199
200impl Display for Ty {
201    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
202        fn list_like(args: &[(Name, Ty)]) -> String {
203            args.iter()
204                .map(|(n, t)| format!("{n}:{t}"))
205                .collect::<Vec<String>>()
206                .join(",")
207        }
208
209        match self {
210            Self::Nil => f.write_str("nil"),
211            Self::Any => f.write_str("any"),
212            Self::Unknown => f.write_str("unknown"),
213            Self::Boolean => f.write_str("boolean"),
214            Self::String => f.write_str("string"),
215            Self::Number => f.write_str("number"),
216            Self::Integer => f.write_str("integer"),
217            Self::Function => f.write_str("function"),
218            Self::Thread => f.write_str("thread"),
219            Self::Userdata => f.write_str("userdata"),
220            Self::Lightuserdata => f.write_str("lightuserdata"),
221            Self::Ref(id) => f.write_str(id),
222            Self::Array(ty) => {
223                f.write_str(&ty.to_string())?;
224                f.write_str("[]")
225            }
226            Self::Table(kv) => match kv {
227                Some((k, v)) => {
228                    f.write_str("table<")?;
229                    f.write_str(&k.to_string())?;
230                    f.write_str(",")?;
231                    f.write_str(&v.to_string())?;
232                    f.write_str(">")
233                }
234                None => f.write_str("table"),
235            },
236            Self::Fun(args, ret) => {
237                f.write_str("fun(")?;
238                f.write_str(&list_like(args))?;
239                f.write_str(")")?;
240                if let Some(ret) = ret {
241                    f.write_str(":")?;
242                    f.write_str(
243                        &ret.iter()
244                            .map(|r| r.to_string())
245                            .collect::<Vec<String>>()
246                            .join(","),
247                    )?;
248                }
249                Ok(())
250            }
251            Self::Dict(kv) => {
252                f.write_str("{")?;
253                f.write_str(&list_like(kv))?;
254                f.write_str("}")
255            }
256            Self::Union(rhs, lhs) => {
257                f.write_str(&rhs.to_string())?;
258                f.write_str("|")?;
259                f.write_str(&lhs.to_string())
260            }
261            Self::Member(mem) => mem.fmt(f),
262        }
263    }
264}