erl_pp/
directive.rs

1use erl_tokenize::tokens::{AtomToken, SymbolToken};
2use erl_tokenize::values::Symbol;
3use erl_tokenize::{LexicalToken, Position, PositionRange};
4use std::fmt;
5
6use crate::directives;
7use crate::token_reader::{ReadFrom, TokenReader};
8use crate::{Error, Result};
9
10/// Macro directive.
11#[derive(Debug, Clone)]
12#[allow(missing_docs)]
13#[allow(clippy::large_enum_variant)]
14pub enum Directive {
15    Include(directives::Include),
16    IncludeLib(directives::IncludeLib),
17    Define(directives::Define),
18    Undef(directives::Undef),
19    Ifdef(directives::Ifdef),
20    Ifndef(directives::Ifndef),
21    Else(directives::Else),
22    Endif(directives::Endif),
23    Error(directives::Error),
24    Warning(directives::Warning),
25}
26impl PositionRange for Directive {
27    fn start_position(&self) -> Position {
28        match *self {
29            Directive::Include(ref t) => t.start_position(),
30            Directive::IncludeLib(ref t) => t.start_position(),
31            Directive::Define(ref t) => t.start_position(),
32            Directive::Undef(ref t) => t.start_position(),
33            Directive::Ifdef(ref t) => t.start_position(),
34            Directive::Ifndef(ref t) => t.start_position(),
35            Directive::Else(ref t) => t.start_position(),
36            Directive::Endif(ref t) => t.start_position(),
37            Directive::Error(ref t) => t.start_position(),
38            Directive::Warning(ref t) => t.start_position(),
39        }
40    }
41    fn end_position(&self) -> Position {
42        match *self {
43            Directive::Include(ref t) => t.end_position(),
44            Directive::IncludeLib(ref t) => t.end_position(),
45            Directive::Define(ref t) => t.end_position(),
46            Directive::Undef(ref t) => t.end_position(),
47            Directive::Ifdef(ref t) => t.end_position(),
48            Directive::Ifndef(ref t) => t.end_position(),
49            Directive::Else(ref t) => t.end_position(),
50            Directive::Endif(ref t) => t.end_position(),
51            Directive::Error(ref t) => t.end_position(),
52            Directive::Warning(ref t) => t.end_position(),
53        }
54    }
55}
56impl fmt::Display for Directive {
57    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
58        match *self {
59            Directive::Include(ref t) => t.fmt(f),
60            Directive::IncludeLib(ref t) => t.fmt(f),
61            Directive::Define(ref t) => t.fmt(f),
62            Directive::Undef(ref t) => t.fmt(f),
63            Directive::Ifdef(ref t) => t.fmt(f),
64            Directive::Ifndef(ref t) => t.fmt(f),
65            Directive::Else(ref t) => t.fmt(f),
66            Directive::Endif(ref t) => t.fmt(f),
67            Directive::Error(ref t) => t.fmt(f),
68            Directive::Warning(ref t) => t.fmt(f),
69        }
70    }
71}
72impl ReadFrom for Directive {
73    fn read_from<T>(reader: &mut TokenReader<T>) -> Result<Self>
74    where
75        T: Iterator<Item = erl_tokenize::Result<LexicalToken>>,
76    {
77        let _hyphen: SymbolToken = reader.read_expected(&Symbol::Hyphen)?;
78        let name: AtomToken = reader
79            .try_read()?
80            .ok_or_else(|| Error::unexpected_token(_hyphen.clone().into(), "-{DIRECTIVE_NAME}"))?;
81
82        reader.unread_token(name.clone().into());
83        reader.unread_token(_hyphen.into());
84        match name.value() {
85            "include" => reader.read().map(Directive::Include),
86            "include_lib" => reader.read().map(Directive::IncludeLib),
87            "define" => reader.read().map(Directive::Define),
88            "undef" => reader.read().map(Directive::Undef),
89            "ifdef" => reader.read().map(Directive::Ifdef),
90            "ifndef" => reader.read().map(Directive::Ifndef),
91            "else" => reader.read().map(Directive::Else),
92            "endif" => reader.read().map(Directive::Endif),
93            "error" => reader.read().map(Directive::Error),
94            "warning" => reader.read().map(Directive::Warning),
95            _ => {
96                let _hyphen: SymbolToken = reader.read_expected(&Symbol::Hyphen)?;
97                Err(Error::unexpected_token(_hyphen.into(), "-{DIRECTIVE_NAME}"))
98            }
99        }
100    }
101}