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 })
34 .collect::<Result<Vec<_>, _>>()?;
35 let name = QualifiedName::new(name, context.src_ref(&node.name.span));
36
37 let decl = match (glob_index.is_some(), &node.use_as) {
38 (false, None) => UseDeclaration::Use(name),
39 (true, None) => UseDeclaration::UseAll(name),
40 (true, Some(_)) => {
41 return Err(ParseError::UseGlobAlias(context.src_ref(&node.span)));
42 }
43 (false, Some(alias)) => {
44 UseDeclaration::UseAs(name, Identifier::from_ast(alias, context)?)
45 }
46 };
47 let visibility = node
48 .visibility
49 .as_ref()
50 .map(|visibility| Visibility::from_ast(visibility, context))
51 .transpose()?;
52 Ok(UseStatement {
53 src_ref: context.src_ref(&node.span),
54 visibility: visibility.unwrap_or_default(),
55 decl,
56 })
57 }
58}
59
60impl FromAst for Visibility {
61 type AstNode = ast::Visibility;
62
63 fn from_ast(node: &Self::AstNode, _context: &ParseContext) -> Result<Self, ParseError> {
64 Ok(match node {
65 ast::Visibility::Public => Self::Public,
66 })
67 }
68}