microcad_lang/parse/
use.rs1use crate::{parse::*, parser::*, syntax::*};
5use microcad_syntax::ast;
6use microcad_syntax::ast::UseStatementPart;
7
8impl FromAst for UseStatement {
9 type AstNode = ast::UseStatement;
10
11 fn from_ast(node: &Self::AstNode, context: &ParseContext) -> Result<Self, ParseError> {
12 let glob_index = node
13 .name
14 .parts
15 .iter()
16 .enumerate()
17 .find(|(_, part)| matches!(part, UseStatementPart::Glob(_)))
18 .map(|(i, _)| i);
19 if let Some(i) = glob_index {
20 if i < node.name.parts.len() - 1 {
21 return Err(ParseError::InvalidGlobPattern(
22 context.src_ref(&node.name.span),
23 ));
24 }
25 }
26 let name = node
27 .name
28 .parts
29 .iter()
30 .filter_map(|part| match part {
31 UseStatementPart::Identifier(ident) => Some(Identifier::from_ast(ident, context)),
32 UseStatementPart::Glob(_) => None,
33 UseStatementPart::Error(_) => None,
34 })
35 .collect::<Result<Vec<_>, _>>()?;
36 let name = QualifiedName::new(name, context.src_ref(&node.name.span));
37
38 let decl = match (glob_index.is_some(), &node.use_as) {
39 (false, None) => UseDeclaration::Use(name),
40 (true, None) => UseDeclaration::UseAll(name),
41 (true, Some(_)) => {
42 return Err(ParseError::UseGlobAlias(context.src_ref(&node.span)));
43 }
44 (false, Some(alias)) => {
45 UseDeclaration::UseAs(name, Identifier::from_ast(alias, context)?)
46 }
47 };
48 let visibility = node
49 .visibility
50 .as_ref()
51 .map(|visibility| Visibility::from_ast(visibility, context))
52 .transpose()?;
53 Ok(UseStatement {
54 keyword_ref: context.src_ref(&node.keyword_span),
55 src_ref: context.src_ref(&node.span),
56 visibility: visibility.unwrap_or_default(),
57 decl,
58 })
59 }
60}
61
62impl FromAst for Visibility {
63 type AstNode = ast::Visibility;
64
65 fn from_ast(node: &Self::AstNode, _context: &ParseContext) -> Result<Self, ParseError> {
66 Ok(match node {
67 ast::Visibility::Public => Self::Public,
68 })
69 }
70}