libmoonwave/tags/
param.rs1use serde::Serialize;
2
3use crate::{diagnostic::Diagnostic, span::Span};
4
5#[derive(Debug, PartialEq, Serialize, Clone)]
6pub struct ParamTag<'a> {
7 pub name: Span<'a>,
8 pub desc: Span<'a>,
9 pub lua_type: Span<'a>,
10 #[serde(skip)]
11 pub source: Span<'a>,
12}
13
14impl<'a> ParamTag<'a> {
15 pub fn parse(span: Span<'a>) -> Result<Self, Diagnostic> {
16 let mut pieces = span.splitn(2, "--");
17 let name_and_maybe_type: Span<'_> = pieces.next().unwrap().trim();
18 let desc = pieces
19 .next()
20 .map(|desc| desc.trim())
21 .unwrap_or_else(|| Span::empty(span.file_id));
22
23 let mut pieces = name_and_maybe_type.splitn(2, " ");
24 let name = pieces.next().unwrap().trim();
25
26 if name.is_empty() {
27 return Err(span.diagnostic("Param name is required"));
28 }
29
30 let lua_type = pieces
31 .next()
32 .map(|name| name.trim())
33 .unwrap_or_else(|| Span::dummy(""));
34
35 Ok(Self {
36 name,
37 desc,
38 lua_type,
39 source: span,
40 })
41 }
42}
43
44#[cfg(test)]
45mod test {
46 use insta::assert_yaml_snapshot;
47
48 use super::*;
49
50 #[test]
51 fn everything_sandwich() {
52 let source = Span::dummy("COOL_NAME foo -- HEY! This is a sweet description");
53
54 let value = ParamTag::parse(source).unwrap();
55 assert_yaml_snapshot!(value, @r###"
56 ---
57 name: COOL_NAME
58 desc: HEY! This is a sweet description
59 lua_type: foo
60 "###);
61 }
62
63 #[test]
64 fn lovecraftian_type() {
65 let source = Span::dummy("foo Roact.Element<{ oh_no: string -> coroutine }> -- I'm sorry.");
66 let value = ParamTag::parse(source).unwrap();
67 assert_yaml_snapshot!(value, @r###"
68 ---
69 name: foo
70 desc: "I'm sorry."
71 lua_type: "Roact.Element<{ oh_no: string -> coroutine }>"
72 "###);
73 }
74
75 #[test]
76 fn no_description() {
77 let source = Span::dummy("coffee tasty");
78 let value = ParamTag::parse(source).unwrap();
79 assert_yaml_snapshot!(value, @r###"
80 ---
81 name: coffee
82 desc: ""
83 lua_type: tasty
84 "###);
85 }
86}