Skip to content

Commit ec96cf5

Browse files
committed
modules
1 parent ee8a8a7 commit ec96cf5

File tree

7 files changed

+248
-115
lines changed

7 files changed

+248
-115
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Option `-f`(`--form`) let you split `lib.rs` on modules, as the `form` tool does
13+
- Option `-o`(`--output`) let you specify output directory path
14+
1015
### Fixed
1116

1217
- Keyword sanitizing (`async`)

src/generate/device.rs

+11-10
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::fs::File;
55
use std::io::Write;
66

77
use crate::errors::*;
8+
use crate::modules::Module;
89
use crate::util::{self, ToSanitizedUpperCase};
910
use crate::Target;
1011

@@ -17,8 +18,8 @@ pub fn render(
1718
nightly: bool,
1819
generic_mod: bool,
1920
device_x: &mut String,
20-
) -> Result<TokenStream> {
21-
let mut out = TokenStream::new();
21+
) -> Result<Module> {
22+
let mut out = Module::new("lib", "");
2223

2324
let doc = format!(
2425
"Peripheral access API for {0} microcontrollers \
@@ -159,16 +160,16 @@ pub fn render(
159160
if generic_mod {
160161
writeln!(File::create("generic.rs").unwrap(), "{}", generic_file).unwrap();
161162
} else {
162-
let tokens = syn::parse_file(generic_file).unwrap().into_token_stream();
163-
164-
out.extend(quote! {
163+
let mut generic_module = Module::new(
164+
"generic",
165+
"Common register and bit access and modify traits",
166+
);
167+
generic_module.out.extend(quote! {
165168
#[allow(unused_imports)]
166169
use generic::*;
167-
///Common register and bit access and modify traits
168-
pub mod generic {
169-
#tokens
170-
}
171170
});
171+
generic_module.extend(syn::parse_file(generic_file).unwrap().into_token_stream());
172+
out.push_module(generic_module);
172173
}
173174

174175
for p in &d.peripherals {
@@ -177,7 +178,7 @@ pub fn render(
177178
continue;
178179
}
179180

180-
out.extend(peripheral::render(
181+
out.push_module(peripheral::render(
181182
p,
182183
&d.peripherals,
183184
&d.default_register_properties,

src/generate/peripheral.rs

+32-46
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::modules::Module;
12
use std::borrow::Cow;
23
use std::cmp::Ordering;
34
use std::collections::HashMap;
@@ -20,9 +21,7 @@ pub fn render(
2021
all_peripherals: &[Peripheral],
2122
defaults: &RegisterProperties,
2223
nightly: bool,
23-
) -> Result<TokenStream> {
24-
let mut out = TokenStream::new();
25-
24+
) -> Result<Module> {
2625
let p_derivedfrom = p_original
2726
.derived_from
2827
.as_ref()
@@ -31,13 +30,19 @@ pub fn render(
3130
let p_merged = p_derivedfrom.map(|ancestor| p_original.derive_from(ancestor));
3231
let p = p_merged.as_ref().unwrap_or(p_original);
3332

33+
let name_sc = p.name.to_sanitized_snake_case();
34+
let description =
35+
util::escape_brackets(util::respace(p.description.as_ref().unwrap_or(&p.name)).as_ref());
36+
37+
let mut module = Module::new(&name_sc, &description);
38+
3439
if p_original.derived_from.is_some() && p_derivedfrom.is_none() {
3540
eprintln!(
3641
"Couldn't find derivedFrom original: {} for {}, skipping",
3742
p_original.derived_from.as_ref().unwrap(),
3843
p_original.name
3944
);
40-
return Ok(out);
45+
return Ok(module);
4146
}
4247

4348
let span = Span::call_site();
@@ -46,15 +51,14 @@ pub fn render(
4651
let description = util::respace(p.description.as_ref().unwrap_or(&p.name));
4752
let derive_regs = p_derivedfrom.is_some() && p_original.registers.is_none();
4853

49-
let name_sc = Ident::new(&p.name.to_sanitized_snake_case(), span);
5054
let base = if derive_regs {
5155
Ident::new(&p_derivedfrom.unwrap().name.to_sanitized_snake_case(), span)
5256
} else {
53-
name_sc.clone()
57+
Ident::new(&name_sc, span)
5458
};
5559

5660
// Insert the peripheral structure
57-
out.extend(quote! {
61+
module.out.extend(quote! {
5862
#[doc = #description]
5963
pub struct #name_pc { _marker: PhantomData<*const ()> }
6064

@@ -81,7 +85,7 @@ pub fn render(
8185
// Derived peripherals may not require re-implementation, and will instead
8286
// use a single definition of the non-derived version.
8387
if derive_regs {
84-
return Ok(out);
88+
return Ok(module);
8589
}
8690

8791
// erc: *E*ither *R*egister or *C*luster
@@ -143,23 +147,22 @@ pub fn render(
143147
// No `struct RegisterBlock` can be generated
144148
if registers.is_empty() && clusters.is_empty() {
145149
// Drop the definition of the peripheral
146-
return Ok(TokenStream::new());
150+
return Ok(Module::new(&name_sc, &description));
147151
}
148152

149153
let defaults = p.default_register_properties.derive_from(defaults);
150154

151155
// Push any register or cluster blocks into the output
152-
let mut mod_items = TokenStream::new();
153-
mod_items.extend(register_or_cluster_block(ercs, &defaults, None, nightly)?);
156+
module.extend(register_or_cluster_block(ercs, &defaults, None, nightly)?);
154157

155158
// Push all cluster related information into the peripheral module
156159
for c in &clusters {
157-
mod_items.extend(cluster_block(c, &defaults, p, all_peripherals, nightly)?);
160+
module.push_module(cluster_block(c, &defaults, p, all_peripherals, nightly)?);
158161
}
159162

160163
// Push all regsiter realted information into the peripheral module
161164
for reg in registers {
162-
mod_items.extend(register::render(
165+
module.push_module(register::render(
163166
reg,
164167
registers,
165168
p,
@@ -168,22 +171,7 @@ pub fn render(
168171
)?);
169172
}
170173

171-
let description =
172-
util::escape_brackets(util::respace(p.description.as_ref().unwrap_or(&p.name)).as_ref());
173-
174-
let open = Punct::new('{', Spacing::Alone);
175-
let close = Punct::new('}', Spacing::Alone);
176-
177-
out.extend(quote! {
178-
#[doc = #description]
179-
pub mod #name_sc #open
180-
});
181-
182-
out.extend(mod_items);
183-
184-
close.to_tokens(&mut out);
185-
186-
Ok(out)
174+
Ok(module)
187175
}
188176

189177
#[derive(Clone, Debug)]
@@ -716,9 +704,7 @@ fn cluster_block(
716704
p: &Peripheral,
717705
all_peripherals: &[Peripheral],
718706
nightly: bool,
719-
) -> Result<TokenStream> {
720-
let mut mod_items = TokenStream::new();
721-
707+
) -> Result<Module> {
722708
// name_sc needs to take into account array type.
723709
let description =
724710
util::escape_brackets(util::respace(c.description.as_ref().unwrap_or(&c.name)).as_ref());
@@ -731,16 +717,25 @@ fn cluster_block(
731717
},
732718
"",
733719
);
734-
let name_sc = Ident::new(&mod_name.to_sanitized_snake_case(), Span::call_site());
720+
721+
let mut module = Module::new(
722+
&mod_name.to_sanitized_snake_case(),
723+
&("Register block\n".to_string() + &description),
724+
);
735725

736726
let defaults = c.default_register_properties.derive_from(defaults);
737727

738-
let reg_block = register_or_cluster_block(&c.children, &defaults, Some(&mod_name), nightly)?;
728+
module.out.extend(register_or_cluster_block(
729+
&c.children,
730+
&defaults,
731+
Some(&mod_name),
732+
nightly,
733+
)?);
739734

740735
// Generate definition for each of the registers.
741736
let registers = util::only_registers(&c.children);
742737
for reg in &registers {
743-
mod_items.extend(register::render(
738+
module.push_module(register::render(
744739
reg,
745740
&registers,
746741
p,
@@ -752,18 +747,9 @@ fn cluster_block(
752747
// Generate the sub-cluster blocks.
753748
let clusters = util::only_clusters(&c.children);
754749
for c in &clusters {
755-
mod_items.extend(cluster_block(c, &defaults, p, all_peripherals, nightly)?);
750+
module.push_module(cluster_block(c, &defaults, p, all_peripherals, nightly)?);
756751
}
757-
758-
Ok(quote! {
759-
#reg_block
760-
761-
///Register block
762-
#[doc = #description]
763-
pub mod #name_sc {
764-
#mod_items
765-
}
766-
})
752+
Ok(module)
767753
}
768754

769755
/// Takes a svd::Register which may be a register array, and turn in into

0 commit comments

Comments
 (0)