java_lang/tree/parser/
package.rs

1use super::{super::PackageDeclaration, identifier, documentation_comment};
2use crate::{ts, Token, TokenStream};
3use nom::{bytes::tag, combinator::opt, multi::separated_list1, IResult, Parser};
4use std::borrow::Cow;
5
6/// 解析包声明从给定的标记流中。
7///
8/// 这个函数接受一个 `TokenStream` 并返回一个 `PackageDeclaration` 以及剩余的标记。
9///
10/// # 参数
11///
12/// * `tokens` - 一个 `TokenStream`,从中解析包声明。
13///
14/// # 返回
15///
16/// 包含剩余标记和 `PackageDeclaration` 的元组。
17///
18/// # 示例
19///
20/// ```
21/// fn main() -> anyhow::Result<()> {
22/// use java_lang::{
23/// TokenStream,
24/// package_declaration
25/// };
26///
27/// let (_, tokens) = TokenStream::from_str(
28///     "package com.test;",
29/// )?;
30/// assert! (!tokens.is_empty());
31///
32/// let (tokens, package) = package_declaration(tokens)?;
33/// assert_eq!(package.name, "com.test");
34///
35/// assert!(tokens.is_empty());
36/// Ok(())
37/// }
38/// ```
39///
40/// # 错误
41///
42/// 如果标记流不包含有效的包声明,这个函数将返回一个错误。
43pub fn package_declaration<'a>(
44    tokens: TokenStream,
45) -> IResult<TokenStream, PackageDeclaration<'a>> {
46    let (tokens, documentation) = opt(documentation_comment).parse(tokens)?;
47    let (tokens, _) = tag(ts![Package]).parse(tokens)?;
48    let (tokens, idents) = separated_list1(tag(ts![Dot]), identifier).parse(tokens)?;
49    let (tokens, _) = tag(ts![SemiColon]).parse(tokens)?;
50    let name = idents
51        .into_iter()
52        .map(|i| i.to_string())
53        .collect::<Vec<_>>()
54        .join(Token::DOT);
55    Ok((
56        tokens,
57        PackageDeclaration {
58            name: Cow::Owned(name),
59            modifiers: Default::default(),
60            documentation,
61        },
62    ))
63}
64
65#[cfg(test)]
66mod tests {
67    use super::*;
68
69    #[test]
70    fn test_package_declaration() -> anyhow::Result<()> {
71        let (_, tokens) = TokenStream::from_str(
72            "\
73            /** 定义包 */
74            package com.test;
75            ",
76        )?;
77        assert!(!tokens.is_empty());
78
79        let (tokens, package) = package_declaration(tokens)?;
80        assert_eq!(
81            package,
82            PackageDeclaration {
83                name: "com.test".into(),
84                modifiers: Default::default(),
85                documentation: Some(" 定义包 ".into())
86            }
87        );
88
89        assert!(tokens.is_empty());
90
91        Ok(())
92    }
93}