stripper_lib/
types.rs

1// Copyright 2016 Gomez Guillaume
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//   http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::borrow::Borrow;
16use std::fmt::{Debug, Display, Error, Formatter};
17
18#[derive(Debug, Clone)]
19pub struct ParseResult {
20    pub event_list: Vec<EventInfo>,
21    pub comment_lines: Vec<usize>,
22    pub original_content: Vec<String>,
23}
24
25#[derive(Clone)]
26pub struct EventInfo {
27    pub line: usize,
28    pub event: EventType,
29}
30
31impl EventInfo {
32    pub fn new(line: usize, event: EventType) -> EventInfo {
33        EventInfo { line, event }
34    }
35}
36
37impl Debug for EventInfo {
38    fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
39        write!(fmt, "{:?}->{:?}", self.line, self.event)
40    }
41}
42
43#[derive(Clone)]
44pub enum EventType {
45    Comment(String),
46    FileComment(String),
47    Type(TypeStruct),
48    InScope,
49    OutScope,
50}
51
52impl Debug for EventType {
53    fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
54        match *self {
55            EventType::Type(ref t) => write!(fmt, "Type: {:?}", t),
56            EventType::FileComment(ref t) => write!(fmt, "FileComment: {:?}", t),
57            EventType::Comment(ref t) => write!(fmt, "Comment: {:?}", t),
58            EventType::InScope => write!(fmt, "InScope"),
59            EventType::OutScope => write!(fmt, "OutScope"),
60        }
61    }
62}
63
64#[derive(Clone, PartialEq)]
65pub struct TypeStruct {
66    pub ty: Type,
67    pub parent: Option<Box<TypeStruct>>,
68    pub name: String,
69    pub args: Vec<String>,
70}
71
72impl TypeStruct {
73    pub fn new(ty: Type, name: &str) -> TypeStruct {
74        TypeStruct {
75            ty,
76            name: name.to_owned(),
77            args: vec![],
78            parent: None,
79        }
80    }
81
82    /*pub fn from_args(ty: Type, args: Vec<String>) -> TypeStruct {
83        TypeStruct {
84            ty: ty,
85            name: String::new(),
86            args: args,
87            parent: None,
88        }
89    }*/
90
91    pub fn empty() -> TypeStruct {
92        TypeStruct {
93            ty: Type::Unknown,
94            name: String::new(),
95            args: Vec::new(),
96            parent: None,
97        }
98    }
99
100    pub fn get_depth(&self, ignore_macros: bool) -> usize {
101        fn recur(ty: &Option<Box<TypeStruct>>, is_parent: bool, ignore_macros: bool) -> usize {
102            match *ty {
103                Some(ref t) => {
104                    if ignore_macros && is_parent && t.ty == Type::Macro {
105                        recur(&t.parent, true, ignore_macros)
106                    } else {
107                        recur(&t.parent, true, ignore_macros) + 1
108                    }
109                }
110                _ => 0,
111            }
112        }
113        recur(&self.parent, false, ignore_macros)
114    }
115}
116
117impl Debug for TypeStruct {
118    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
119        let parent = &self.parent;
120        match *parent {
121            Some(ref p) => write!(
122                f,
123                "{:?}::{} {}{}",
124                p,
125                self.ty,
126                self.name,
127                self.args.join(" ")
128            ),
129            _ => write!(f, "{} {}{}", self.ty, self.name, self.args.join(" ")),
130        }
131    }
132}
133
134fn show(f: &mut Formatter, t: &TypeStruct, is_parent: bool) -> Result<(), Error> {
135    if is_parent {
136        write!(f, "{} {}{}::", t.ty, t.name, t.args.join(" "))
137    } else {
138        write!(f, "{} {}{}", t.ty, t.name, t.args.join(" "))
139    }
140}
141
142fn sub_call(f: &mut Formatter, t: &TypeStruct, is_parent: bool) -> Result<(), Error> {
143    if (t.ty == Type::Macro || t.ty.is_macro_definition()) && is_parent {
144        match t.parent {
145            Some(ref p) => sub_call(f, p.borrow(), true),
146            _ => Ok(()),
147        }
148    } else {
149        match t.parent {
150            Some(ref p) => {
151                sub_call(f, p.borrow(), true)?;
152                show(f, t, is_parent)
153            }
154            _ => show(f, t, is_parent),
155        }
156    }
157}
158
159impl Display for TypeStruct {
160    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
161        sub_call(f, self, false)
162    }
163}
164
165#[derive(Debug, Copy, Clone, PartialEq, Eq)]
166pub enum Type {
167    Struct,
168    Mod,
169    Enum,
170    Fn,
171    Const,
172    Static,
173    Type,
174    Variant,
175    Impl,
176    Use,
177    MacroDefinition,
178    Macro,
179    Trait,
180    Flags,
181    Unknown,
182}
183
184impl Type {
185    pub fn is_macro_definition(self) -> bool {
186        matches!(self, Type::MacroDefinition)
187    }
188}
189
190impl Type {
191    pub fn from(s: &str) -> Type {
192        match s {
193            "struct" => Type::Struct,
194            "mod" => Type::Mod,
195            "enum" => Type::Enum,
196            "fn" => Type::Fn,
197            "const" => Type::Const,
198            "static" => Type::Static,
199            "type" => Type::Type,
200            "impl" => Type::Impl,
201            "use" => Type::Use,
202            "trait" => Type::Trait,
203            "flags" => Type::Flags,
204            "macro" => Type::Macro,
205            "macro_rules" | "macro_rules!" => Type::MacroDefinition,
206            _ => Type::Variant,
207        }
208    }
209}
210
211impl Display for Type {
212    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
213        match *self {
214            Type::Struct => write!(f, "struct"),
215            Type::Mod => write!(f, "mod"),
216            Type::Enum => write!(f, "enum"),
217            Type::Fn => write!(f, "fn"),
218            Type::Const => write!(f, "const"),
219            Type::Static => write!(f, "static"),
220            Type::Type => write!(f, "type"),
221            Type::Variant => write!(f, "variant"),
222            Type::Impl => write!(f, "impl"),
223            Type::Use => write!(f, "use"),
224            Type::Trait => write!(f, "trait"),
225            Type::Macro => write!(f, "macro"),
226            Type::MacroDefinition => write!(f, "macro"),
227            Type::Flags => write!(f, "flags"),
228            _ => write!(f, "?"),
229        }
230    }
231}