Skip to content

Commit f6d0cb0

Browse files
authored
Merge pull request #769 from rust-embedded/config
mode Config to config module
2 parents 2fd1d1f + 8e2d1b9 commit f6d0cb0

File tree

8 files changed

+124
-163
lines changed

8 files changed

+124
-163
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
1616
Add `width`, `offset` methods
1717
- *breaking change* Always numerates field arrays from 0
1818
- Support of default value for `EnumeratedValues`
19+
- move `Config` to `config` module
1920

2021
## [v0.30.3] - 2023-11-19
2122

src/config.rs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
use anyhow::{bail, Result};
2+
use std::path::{Path, PathBuf};
3+
4+
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
5+
#[derive(Clone, PartialEq, Eq, Debug, Default)]
6+
#[cfg_attr(feature = "serde", serde(default))]
7+
pub struct Config {
8+
pub target: Target,
9+
pub atomics: bool,
10+
pub atomics_feature: Option<String>,
11+
pub generic_mod: bool,
12+
pub make_mod: bool,
13+
pub ignore_groups: bool,
14+
pub keep_list: bool,
15+
pub strict: bool,
16+
pub pascal_enum_values: bool,
17+
pub feature_group: bool,
18+
pub feature_peripheral: bool,
19+
pub max_cluster_size: bool,
20+
pub impl_debug: bool,
21+
pub impl_debug_feature: Option<String>,
22+
pub output_dir: Option<PathBuf>,
23+
pub input: Option<PathBuf>,
24+
pub source_type: SourceType,
25+
pub log_level: Option<String>,
26+
pub interrupt_link_section: Option<String>,
27+
pub reexport_core_peripherals: bool,
28+
pub reexport_interrupt: bool,
29+
}
30+
31+
#[allow(clippy::upper_case_acronyms)]
32+
#[allow(non_camel_case_types)]
33+
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
34+
#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
35+
pub enum Target {
36+
#[cfg_attr(feature = "serde", serde(rename = "cortex-m"))]
37+
#[default]
38+
CortexM,
39+
#[cfg_attr(feature = "serde", serde(rename = "msp430"))]
40+
Msp430,
41+
#[cfg_attr(feature = "serde", serde(rename = "riscv"))]
42+
RISCV,
43+
#[cfg_attr(feature = "serde", serde(rename = "xtensa-lx"))]
44+
XtensaLX,
45+
#[cfg_attr(feature = "serde", serde(rename = "mips"))]
46+
Mips,
47+
#[cfg_attr(feature = "serde", serde(rename = "none"))]
48+
None,
49+
}
50+
51+
impl Target {
52+
pub fn parse(s: &str) -> Result<Self> {
53+
Ok(match s {
54+
"cortex-m" => Target::CortexM,
55+
"msp430" => Target::Msp430,
56+
"riscv" => Target::RISCV,
57+
"xtensa-lx" => Target::XtensaLX,
58+
"mips" => Target::Mips,
59+
"none" => Target::None,
60+
_ => bail!("unknown target {}", s),
61+
})
62+
}
63+
}
64+
65+
#[cfg_attr(
66+
feature = "serde",
67+
derive(serde::Deserialize),
68+
serde(rename_all = "lowercase")
69+
)]
70+
#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
71+
pub enum SourceType {
72+
#[default]
73+
Xml,
74+
#[cfg(feature = "yaml")]
75+
Yaml,
76+
#[cfg(feature = "json")]
77+
Json,
78+
}
79+
80+
impl SourceType {
81+
/// Make a new [`SourceType`] from a given extension.
82+
pub fn from_extension(s: &str) -> Option<Self> {
83+
match s {
84+
"svd" | "xml" => Some(Self::Xml),
85+
#[cfg(feature = "yaml")]
86+
"yml" | "yaml" => Some(Self::Yaml),
87+
#[cfg(feature = "json")]
88+
"json" => Some(Self::Json),
89+
_ => None,
90+
}
91+
}
92+
pub fn from_path(path: &Path) -> Self {
93+
path.extension()
94+
.and_then(|e| e.to_str())
95+
.and_then(Self::from_extension)
96+
.unwrap_or_default()
97+
}
98+
}

src/generate/device.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ use log::debug;
66
use std::borrow::Cow;
77
use std::fs::File;
88
use std::io::Write;
9+
use std::path::Path;
910

10-
use crate::util::{self, Config, ToSanitizedCase};
11-
use crate::Target;
11+
use crate::config::{Config, Target};
12+
use crate::util::{self, ToSanitizedCase};
1213
use anyhow::{Context, Result};
1314

1415
use crate::generate::{interrupt, peripheral};
@@ -139,7 +140,13 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
139140
let generic_file = include_str!("generic.rs");
140141
let generic_atomic_file = include_str!("generic_atomic.rs");
141142
if config.generic_mod {
142-
let mut file = File::create(config.output_dir.join("generic.rs"))?;
143+
let mut file = File::create(
144+
config
145+
.output_dir
146+
.as_deref()
147+
.unwrap_or(Path::new("."))
148+
.join("generic.rs"),
149+
)?;
143150
writeln!(file, "{generic_file}")?;
144151
if config.atomics {
145152
if let Some(atomics_feature) = config.atomics_feature.as_ref() {

src/generate/peripheral.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use svd_parser::expand::{
66
derive_cluster, derive_peripheral, derive_register, BlockPath, Index, RegisterPath,
77
};
88

9+
use crate::config::Config;
910
use crate::svd::{
1011
self, Cluster, ClusterInfo, MaybeArray, Peripheral, Register, RegisterCluster, RegisterInfo,
1112
};
@@ -15,8 +16,8 @@ use quote::{quote, ToTokens};
1516
use syn::{punctuated::Punctuated, Token};
1617

1718
use crate::util::{
18-
self, name_to_ty, path_segment, type_path, unsuffixed, zst_type, Config, FullName,
19-
ToSanitizedCase, BITS_PER_BYTE,
19+
self, name_to_ty, path_segment, type_path, unsuffixed, zst_type, FullName, ToSanitizedCase,
20+
BITS_PER_BYTE,
2021
};
2122
use anyhow::{anyhow, bail, Context, Result};
2223

src/generate/register.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ use svd_parser::expand::{
1313
derive_enumerated_values, derive_field, BlockPath, EnumPath, FieldPath, Index, RegisterPath,
1414
};
1515

16+
use crate::config::Config;
1617
use crate::util::{
17-
self, ident_to_path, path_segment, replace_suffix, type_path, unsuffixed, Config, FullName,
18+
self, ident_to_path, path_segment, replace_suffix, type_path, unsuffixed, FullName,
1819
ToSanitizedCase, U32Ext,
1920
};
2021
use anyhow::{anyhow, Result};

src/lib.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -538,10 +538,11 @@
538538
use quote::quote;
539539
use svd_parser::svd;
540540

541+
pub mod config;
541542
pub mod generate;
542543
pub mod util;
543544

544-
pub use crate::util::{Config, Target};
545+
pub use config::{Config, Target};
545546

546547
#[non_exhaustive]
547548
pub struct Generation {
@@ -599,9 +600,9 @@ pub fn generate(input: &str, config: &Config) -> Result<Generation> {
599600
})
600601
}
601602

602-
/// Load a [Device](svd::Device) from a string slice with given [config](crate::util::Config).
603-
pub fn load_from(input: &str, config: &crate::util::Config) -> Result<svd::Device> {
604-
use self::util::SourceType;
603+
/// Load a [Device](svd::Device) from a string slice with given [config](crate::config::Config).
604+
pub fn load_from(input: &str, config: &Config) -> Result<svd::Device> {
605+
use config::SourceType;
605606
use svd_parser::ValidateLevel;
606607

607608
let mut device = match config.source_type {

src/main.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@
22

33
use log::{debug, error, info};
44

5-
use std::fs::File;
65
use std::io::Write;
76
use std::process;
7+
use std::{fs::File, path::Path};
88

99
use anyhow::{Context, Result};
1010
use clap::{Arg, ArgAction, Command};
1111

1212
use svd2rust::{
13+
config::{Config, SourceType, Target},
1314
generate, load_from,
14-
util::{self, build_rs, Config, SourceType, Target},
15+
util::{self, build_rs},
1516
};
1617

1718
fn parse_configs(app: Command) -> Result<Config> {
@@ -216,7 +217,7 @@ fn run() -> Result<()> {
216217
if let Some(file) = config.input.as_ref() {
217218
config.source_type = SourceType::from_path(file)
218219
}
219-
let path = &config.output_dir;
220+
let path = config.output_dir.as_deref().unwrap_or(Path::new("."));
220221

221222
info!("Parsing device from SVD file");
222223
let device = load_from(input, &config)?;

src/util.rs

Lines changed: 1 addition & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -6,68 +6,20 @@ use inflections::Inflect;
66
use proc_macro2::{Ident, Span, TokenStream};
77
use quote::quote;
88
use std::collections::HashSet;
9-
use std::path::{Path, PathBuf};
109
use svd_rs::{MaybeArray, Peripheral, PeripheralInfo};
1110

1211
use syn::{
1312
punctuated::Punctuated, token::PathSep, Lit, LitInt, PathArguments, PathSegment, Type, TypePath,
1413
};
1514

16-
use anyhow::{anyhow, bail, Result};
15+
use anyhow::{anyhow, Result};
1716

1817
pub const BITS_PER_BYTE: u32 = 8;
1918

2019
/// List of chars that some vendors use in their peripheral/field names but
2120
/// that are not valid in Rust ident
2221
const BLACKLIST_CHARS: &[char] = &['(', ')', '[', ']', '/', ' ', '-'];
2322

24-
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
25-
#[derive(Clone, PartialEq, Eq, Debug)]
26-
pub struct Config {
27-
#[cfg_attr(feature = "serde", serde(default))]
28-
pub target: Target,
29-
#[cfg_attr(feature = "serde", serde(default))]
30-
pub atomics: bool,
31-
#[cfg_attr(feature = "serde", serde(default))]
32-
pub atomics_feature: Option<String>,
33-
#[cfg_attr(feature = "serde", serde(default))]
34-
pub generic_mod: bool,
35-
#[cfg_attr(feature = "serde", serde(default))]
36-
pub make_mod: bool,
37-
#[cfg_attr(feature = "serde", serde(default))]
38-
pub ignore_groups: bool,
39-
#[cfg_attr(feature = "serde", serde(default))]
40-
pub keep_list: bool,
41-
#[cfg_attr(feature = "serde", serde(default))]
42-
pub strict: bool,
43-
#[cfg_attr(feature = "serde", serde(default))]
44-
pub pascal_enum_values: bool,
45-
#[cfg_attr(feature = "serde", serde(default))]
46-
pub feature_group: bool,
47-
#[cfg_attr(feature = "serde", serde(default))]
48-
pub feature_peripheral: bool,
49-
#[cfg_attr(feature = "serde", serde(default))]
50-
pub max_cluster_size: bool,
51-
#[cfg_attr(feature = "serde", serde(default))]
52-
pub impl_debug: bool,
53-
#[cfg_attr(feature = "serde", serde(default))]
54-
pub impl_debug_feature: Option<String>,
55-
#[cfg_attr(feature = "serde", serde(default = "current_dir"))]
56-
pub output_dir: PathBuf,
57-
#[cfg_attr(feature = "serde", serde(default))]
58-
pub input: Option<PathBuf>,
59-
#[cfg_attr(feature = "serde", serde(default))]
60-
pub source_type: SourceType,
61-
#[cfg_attr(feature = "serde", serde(default))]
62-
pub log_level: Option<String>,
63-
#[cfg_attr(feature = "serde", serde(default))]
64-
pub interrupt_link_section: Option<String>,
65-
#[cfg_attr(feature = "serde", serde(default))]
66-
pub reexport_core_peripherals: bool,
67-
#[cfg_attr(feature = "serde", serde(default))]
68-
pub reexport_interrupt: bool,
69-
}
70-
7123
#[derive(Clone, Debug, PartialEq, Eq)]
7224
pub enum Case {
7325
Constant,
@@ -103,107 +55,6 @@ impl Case {
10355
}
10456
}
10557

106-
fn current_dir() -> PathBuf {
107-
PathBuf::from(".")
108-
}
109-
110-
impl Default for Config {
111-
fn default() -> Self {
112-
Self {
113-
target: Target::default(),
114-
atomics: false,
115-
atomics_feature: None,
116-
generic_mod: false,
117-
make_mod: false,
118-
ignore_groups: false,
119-
keep_list: false,
120-
strict: false,
121-
pascal_enum_values: false,
122-
feature_group: false,
123-
feature_peripheral: false,
124-
max_cluster_size: false,
125-
impl_debug: false,
126-
impl_debug_feature: None,
127-
output_dir: current_dir(),
128-
input: None,
129-
source_type: SourceType::default(),
130-
log_level: None,
131-
interrupt_link_section: None,
132-
reexport_core_peripherals: false,
133-
reexport_interrupt: false,
134-
}
135-
}
136-
}
137-
138-
#[allow(clippy::upper_case_acronyms)]
139-
#[allow(non_camel_case_types)]
140-
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
141-
#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
142-
pub enum Target {
143-
#[cfg_attr(feature = "serde", serde(rename = "cortex-m"))]
144-
#[default]
145-
CortexM,
146-
#[cfg_attr(feature = "serde", serde(rename = "msp430"))]
147-
Msp430,
148-
#[cfg_attr(feature = "serde", serde(rename = "riscv"))]
149-
RISCV,
150-
#[cfg_attr(feature = "serde", serde(rename = "xtensa-lx"))]
151-
XtensaLX,
152-
#[cfg_attr(feature = "serde", serde(rename = "mips"))]
153-
Mips,
154-
#[cfg_attr(feature = "serde", serde(rename = "none"))]
155-
None,
156-
}
157-
158-
impl Target {
159-
pub fn parse(s: &str) -> Result<Self> {
160-
Ok(match s {
161-
"cortex-m" => Target::CortexM,
162-
"msp430" => Target::Msp430,
163-
"riscv" => Target::RISCV,
164-
"xtensa-lx" => Target::XtensaLX,
165-
"mips" => Target::Mips,
166-
"none" => Target::None,
167-
_ => bail!("unknown target {}", s),
168-
})
169-
}
170-
}
171-
172-
#[cfg_attr(
173-
feature = "serde",
174-
derive(serde::Deserialize),
175-
serde(rename_all = "lowercase")
176-
)]
177-
#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
178-
pub enum SourceType {
179-
#[default]
180-
Xml,
181-
#[cfg(feature = "yaml")]
182-
Yaml,
183-
#[cfg(feature = "json")]
184-
Json,
185-
}
186-
187-
impl SourceType {
188-
/// Make a new [`SourceType`] from a given extension.
189-
pub fn from_extension(s: &str) -> Option<Self> {
190-
match s {
191-
"svd" | "xml" => Some(Self::Xml),
192-
#[cfg(feature = "yaml")]
193-
"yml" | "yaml" => Some(Self::Yaml),
194-
#[cfg(feature = "json")]
195-
"json" => Some(Self::Json),
196-
_ => None,
197-
}
198-
}
199-
pub fn from_path(path: &Path) -> Self {
200-
path.extension()
201-
.and_then(|e| e.to_str())
202-
.and_then(Self::from_extension)
203-
.unwrap_or_default()
204-
}
205-
}
206-
20758
/// Convert self string into specific case without overlapping to svd2rust internal names
20859
pub trait ToSanitizedCase {
20960
/// Convert self into PascalCase.

0 commit comments

Comments
 (0)