Skip to content

Commit 02c2aff

Browse files
committed
1. Code refactoring
2. Correction of empty types `tt`, `str`, `arr`
1 parent 0152dc1 commit 02c2aff

File tree

9 files changed

+193
-86
lines changed

9 files changed

+193
-86
lines changed

src/exprs/literal.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,14 @@ impl ExprLit {
129129
});
130130
}
131131

132-
if let (Some(b'"'), Some(b'"')) = (a_array.get(0), a_array.get(len-1)) {} else
133-
if let (Some(b'\''), Some(b'\'')) = (a_array.get(0), a_array.get(len-1)) {
134-
if len != 3 {
132+
debug_assert_eq!(a_array.get(0).is_some(), true);
133+
debug_assert_eq!(a_array.get(len -1).is_some(), true);
134+
/*
135+
This is safe, the extra necessary checks are done in a separate `if` above.
136+
*/
137+
match unsafe { (a_array.get_unchecked(0), a_array.get_unchecked(len -1)) } {
138+
(b'"', b'"') => /* line */ {}, // GOOD,
139+
(b'\'', b'\'') if len != 3 => { /* one_symbol */
135140
/*
136141
We exclude the possibility of using `'` as more
137142
than one character.
@@ -141,18 +146,19 @@ impl ExprLit {
141146
current: len,
142147
exp: 3
143148
}
144-
)
145-
}
146-
} else {
147-
return err(ExprLitTryNewErr::ExpQuotes);
149+
);
150+
},
151+
(b'\'', b'\'') => /* line */ {}, // GOOD,
152+
_ => return err(ExprLitTryNewErr::ExpQuotes),
148153
}
149154

150155
next({
151156
debug_assert_eq!(a.get(1..len-1).is_some(), true);
152157

153-
Self::__new(unsafe {
158+
let str = unsafe {
154159
a.get_unchecked(1..len-1)
155-
})
160+
};
161+
Self::__new(str)
156162
})
157163
}
158164

@@ -209,6 +215,12 @@ impl ExprLit {
209215
)
210216
}
211217

218+
#[inline(always)]
219+
/// Returns `true` if self has a length of zero bytes.
220+
pub const fn is_empty(&self) -> bool {
221+
self.data.is_empty()
222+
}
223+
212224
/// Getting a string of actual data.
213225
#[inline(always)]
214226
pub const fn as_str(&self) -> &str {

src/lib.rs

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -140,22 +140,14 @@ fn search_include_and_replacegroup(
140140
if punct2.as_char() == '!' {
141141
if let Some(m_group) = iter.next() {
142142
if let TokenTree2::Group(group) = m_group {
143-
let result = ttry!(macro_fn(
144-
group,
145-
));
143+
let result = ttry!( macro_fn(group) );
146144

147-
match result {
148-
None => {}, // skip,
149-
Some(new_tt) => {
150-
let nulltt = make_null_ttree();
151-
152-
*m_ident = nulltt.clone();
153-
*m_punct = nulltt.clone();
154-
*m_punct2 = nulltt;
155-
156-
*m_group = new_tt;
157-
},
158-
}
145+
let nulltt = make_null_ttree();
146+
147+
*m_ident = nulltt.clone();
148+
*m_punct = nulltt.clone();
149+
*m_punct2 = nulltt.clone();
150+
*m_group = result;
159151
}
160152
}
161153
}

src/macros/include.rs

Lines changed: 81 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
use std::{io::Read, fs::File};
33
use proc_macro2::{TokenTree as TokenTree2, Group, TokenStream as TokenStream2, Delimiter, Span, Literal};
4-
use crate::{trees::{sg_err, result::TreeResult, loader::{load_file_and_automake_tree, LoadFileAndAutoMakeTreeErr}, ttry, group::g_stringify}, exprs::literal::{ExprLit, ExprLitTryNewErr}};
4+
use crate::{trees::{sg_err, result::TreeResult, loader::{load_file_and_automake_tree_fn, LoadFileAndAutoMakeTreeErr}, ttry, group::g_stringify}, exprs::literal::{ExprLit, ExprLitTryNewErr}};
55

66
/// A trait that specifies the final behavior for the `include` macro.
77
pub trait BehMacroInclude {
@@ -16,10 +16,14 @@ pub trait BehMacroInclude {
1616
group_span: Span,
1717
// `span` indicating a literal occurrence or group describing a future path.
1818
literal_span: Span
19-
) -> TreeResult<Option<Self::Result>>;
19+
) -> TreeResult<Self::Result>;
20+
21+
/// Create an empty valid tree.
22+
fn make_empty_tree(
23+
group_span: Span,
24+
) -> Self::Result;
2025
}
2126

22-
2327
/// An argument, basically a path, written in `literals` or created with
2428
/// a `group` via `stringify`.
2529
#[derive(Debug)]
@@ -32,9 +36,10 @@ pub enum BehMacroArg0 {
3236
}
3337

3438
impl BehMacroArg0 {
35-
/// Get a data string without special characters, with final escaping (if required).
39+
/// Get a data string without special characters,
40+
/// with final escaping (if required).
3641
#[inline]
37-
pub fn get_str<R>(
42+
pub fn get_str_fn<R>(
3843
&self,
3944

4045
next: impl FnOnce(&'_ str) -> R,
@@ -45,7 +50,12 @@ impl BehMacroArg0 {
4550
Self::ExpMakeExprLit(a) => {
4651
ExprLit::try_new_fn(
4752
a,
48-
|a| next(&a),
53+
|a| {
54+
let result = next(&a);
55+
drop(a);
56+
57+
result
58+
},
4959
err
5060
)
5161
}
@@ -59,15 +69,25 @@ pub (crate) enum IncludeTt {}
5969

6070
impl BehMacroInclude for IncludeTt {
6171
type Result = TokenTree2;
62-
72+
73+
fn make_empty_tree(group_span: Span) -> Self::Result {
74+
let mut ngroup = Group::new(
75+
Delimiter::None,
76+
TokenStream2::new(),
77+
);
78+
ngroup.set_span(group_span);
79+
80+
TokenTree2::Group(ngroup)
81+
}
82+
6383
fn make_tree(
6484
arg0: BehMacroArg0,
6585

6686
group_span: Span,
6787
literal_span: Span,
68-
) -> TreeResult<Option<Self::Result>> {
69-
arg0.get_str(
70-
|sspath| load_file_and_automake_tree(
88+
) -> TreeResult<Self::Result> {
89+
arg0.get_str_fn(
90+
|sspath| load_file_and_automake_tree_fn(
7191
sspath,
7292

7393
|_| {},
@@ -84,7 +104,7 @@ impl BehMacroInclude for IncludeTt {
84104
ngroup.set_span(group_span);
85105

86106
return TreeResult::Ok(
87-
Some(TokenTree2::Group(ngroup))
107+
TokenTree2::Group(ngroup)
88108
);
89109
},
90110
|e| TreeResult::Err(e.into_tt_err(literal_span)),
@@ -102,15 +122,25 @@ pub (crate) enum IncludeTtAndFixUnkStartToken {}
102122

103123
impl BehMacroInclude for IncludeTtAndFixUnkStartToken {
104124
type Result = TokenTree2;
105-
125+
126+
fn make_empty_tree(group_span: Span) -> Self::Result {
127+
let mut ngroup = Group::new(
128+
Delimiter::None,
129+
TokenStream2::new(),
130+
);
131+
ngroup.set_span(group_span);
132+
133+
TokenTree2::Group(ngroup)
134+
}
135+
106136
fn make_tree(
107137
arg0: BehMacroArg0,
108138

109139
group_span: Span,
110140
literal_span: Span,
111-
) -> TreeResult<Option<Self::Result>> {
112-
arg0.get_str(
113-
|sspath| load_file_and_automake_tree(
141+
) -> TreeResult<Self::Result> {
142+
arg0.get_str_fn(
143+
|sspath| load_file_and_automake_tree_fn(
114144
sspath,
115145

116146
|p_string| { /*fix unk start token*/
@@ -177,7 +207,7 @@ impl BehMacroInclude for IncludeTtAndFixUnkStartToken {
177207
ngroup.set_span(group_span);
178208

179209
return TreeResult::Ok(
180-
Some(TokenTree2::Group(ngroup))
210+
TokenTree2::Group(ngroup)
181211
);
182212
},
183213
|e| TreeResult::Err(e.into_tt_err(literal_span)),
@@ -194,30 +224,34 @@ pub (crate) enum IncludeStr {}
194224
impl BehMacroInclude for IncludeStr {
195225
type Result = TokenTree2;
196226

227+
fn make_empty_tree(group_span: Span) -> Self::Result {
228+
let mut lit = Literal::string("");
229+
lit.set_span(group_span);
230+
231+
TokenTree2::Literal(lit)
232+
}
233+
197234
fn make_tree(
198235
arg0: BehMacroArg0,
199236

200237
group_span: Span,
201238
literal_span: Span
202-
) -> TreeResult<Option<Self::Result>> {
203-
arg0.get_str(
239+
) -> TreeResult<Self::Result> {
240+
arg0.get_str_fn(
204241
|sspath| {
205242
let data = match std::fs::read_to_string(sspath) {
206243
Ok(a) => a,
207-
Err(e) => return LoadFileAndAutoMakeTreeErr::ReadToString {
208-
err: e,
209-
path: sspath
210-
}
211-
.into_tt_err(literal_span)
212-
.into(),
244+
Err(e) => return LoadFileAndAutoMakeTreeErr::read_to_string(e, sspath)
245+
.into_tt_err(literal_span)
246+
.into(),
213247
};
214248

215249
let mut lit = Literal::string(&data);
216250
lit.set_span(group_span);
217251

218-
return TreeResult::Ok(
219-
Some(TokenTree2::Literal(lit))
220-
);
252+
TreeResult::Ok(
253+
TokenTree2::Literal(lit)
254+
)
221255
},
222256
|e| TreeResult::Err(e.into_tt_err(literal_span)),
223257
)
@@ -231,33 +265,34 @@ pub (crate) enum IncludeArr {}
231265
impl BehMacroInclude for IncludeArr {
232266
type Result = TokenTree2;
233267

268+
fn make_empty_tree(group_span: Span) -> Self::Result {
269+
let mut lit = Literal::byte_string(&[]);
270+
lit.set_span(group_span);
271+
272+
TokenTree2::Literal(lit)
273+
}
274+
234275
fn make_tree(
235276
arg0: BehMacroArg0,
236277

237278
group_span: Span,
238279
literal_span: Span
239-
) -> TreeResult<Option<Self::Result>> {
240-
arg0.get_str(
280+
) -> TreeResult<Self::Result> {
281+
arg0.get_str_fn(
241282
|sspath| {
242283
let vec = {
243284
let mut file = match File::open(sspath) {
244285
Ok(a) => a,
245-
Err(e) => return LoadFileAndAutoMakeTreeErr::ReadToString {
246-
err: e,
247-
path: sspath
248-
}
249-
.into_tt_err(literal_span)
250-
.into(),
286+
Err(e) => return LoadFileAndAutoMakeTreeErr::read_to_string(e, sspath)
287+
.into_tt_err(literal_span)
288+
.into(),
251289
};
252290

253291
let mut vec = Vec::new(); // capacity is not required.
254292
if let Err(e) = file.read_to_end(&mut vec) {
255-
return LoadFileAndAutoMakeTreeErr::ReadToString {
256-
err: e,
257-
path: sspath
258-
}
259-
.into_tt_err(literal_span)
260-
.into();
293+
return LoadFileAndAutoMakeTreeErr::read_to_string(e, sspath)
294+
.into_tt_err(literal_span)
295+
.into();
261296
};
262297

263298
vec
@@ -267,7 +302,7 @@ impl BehMacroInclude for IncludeArr {
267302
lit.set_span(group_span);
268303

269304
return TreeResult::Ok(
270-
Some(TokenTree2::Literal(lit))
305+
TokenTree2::Literal(lit)
271306
);
272307
},
273308
|e| TreeResult::Err(e.into_tt_err(literal_span)),
@@ -278,7 +313,7 @@ impl BehMacroInclude for IncludeArr {
278313
/// Build macro `include`/`include_str`/`include_arr`.
279314
pub fn macro_rule_include<A>(
280315
group: &'_ Group,
281-
) -> TreeResult<Option<A::Result>> where A: BehMacroInclude {
316+
) -> TreeResult<A::Result> where A: BehMacroInclude {
282317
let stream0 = {
283318
let all_streams = group.stream();
284319
let mut iter = all_streams.into_iter();
@@ -294,20 +329,20 @@ pub fn macro_rule_include<A>(
294329
};
295330

296331
match stream0 {
297-
None => TreeResult::Ok(None),
332+
None => TreeResult::Ok( A::make_empty_tree(group.span()) ),
298333
Some(TokenTree2::Group(g_stream)) => {
299334
// The path is a group of TokenTrees that can be converted to
300335
// a string and concatenated.
301336

302-
match ttry!(g_stringify(&g_stream)) {
337+
match ttry!( g_stringify(&g_stream) ) {
303338
Some(stringify) => A::make_tree(
304339
// The value is already ready to be used as a path.
305340
BehMacroArg0::Stringify(stringify),
306341

307342
group.span(),
308343
g_stream.span()
309344
),
310-
None => TreeResult::Ok(None),
345+
None => TreeResult::Ok( A::make_empty_tree(group.span()) ),
311346
}
312347
},
313348
Some(TokenTree2::Literal(literal)) => {

0 commit comments

Comments
 (0)