diff --git a/CHANGELOG.md b/CHANGELOG.md index 2bde91f5..217eaa0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/). Add `width`, `offset` methods - *breaking change* Always numerates field arrays from 0 - Support of default value for `EnumeratedValues` +- move `Config` to `config` module ## [v0.30.3] - 2023-11-19 diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 00000000..e1c07c7e --- /dev/null +++ b/src/config.rs @@ -0,0 +1,98 @@ +use anyhow::{bail, Result}; +use std::path::{Path, PathBuf}; + +#[cfg_attr(feature = "serde", derive(serde::Deserialize))] +#[derive(Clone, PartialEq, Eq, Debug, Default)] +#[cfg_attr(feature = "serde", serde(default))] +pub struct Config { + pub target: Target, + pub atomics: bool, + pub atomics_feature: Option, + pub generic_mod: bool, + pub make_mod: bool, + pub ignore_groups: bool, + pub keep_list: bool, + pub strict: bool, + pub pascal_enum_values: bool, + pub feature_group: bool, + pub feature_peripheral: bool, + pub max_cluster_size: bool, + pub impl_debug: bool, + pub impl_debug_feature: Option, + pub output_dir: Option, + pub input: Option, + pub source_type: SourceType, + pub log_level: Option, + pub interrupt_link_section: Option, + pub reexport_core_peripherals: bool, + pub reexport_interrupt: bool, +} + +#[allow(clippy::upper_case_acronyms)] +#[allow(non_camel_case_types)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize))] +#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)] +pub enum Target { + #[cfg_attr(feature = "serde", serde(rename = "cortex-m"))] + #[default] + CortexM, + #[cfg_attr(feature = "serde", serde(rename = "msp430"))] + Msp430, + #[cfg_attr(feature = "serde", serde(rename = "riscv"))] + RISCV, + #[cfg_attr(feature = "serde", serde(rename = "xtensa-lx"))] + XtensaLX, + #[cfg_attr(feature = "serde", serde(rename = "mips"))] + Mips, + #[cfg_attr(feature = "serde", serde(rename = "none"))] + None, +} + +impl Target { + pub fn parse(s: &str) -> Result { + Ok(match s { + "cortex-m" => Target::CortexM, + "msp430" => Target::Msp430, + "riscv" => Target::RISCV, + "xtensa-lx" => Target::XtensaLX, + "mips" => Target::Mips, + "none" => Target::None, + _ => bail!("unknown target {}", s), + }) + } +} + +#[cfg_attr( + feature = "serde", + derive(serde::Deserialize), + serde(rename_all = "lowercase") +)] +#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)] +pub enum SourceType { + #[default] + Xml, + #[cfg(feature = "yaml")] + Yaml, + #[cfg(feature = "json")] + Json, +} + +impl SourceType { + /// Make a new [`SourceType`] from a given extension. + pub fn from_extension(s: &str) -> Option { + match s { + "svd" | "xml" => Some(Self::Xml), + #[cfg(feature = "yaml")] + "yml" | "yaml" => Some(Self::Yaml), + #[cfg(feature = "json")] + "json" => Some(Self::Json), + _ => None, + } + } + pub fn from_path(path: &Path) -> Self { + path.extension() + .and_then(|e| e.to_str()) + .and_then(Self::from_extension) + .unwrap_or_default() + } +} diff --git a/src/generate/device.rs b/src/generate/device.rs index 713d6719..36413f63 100644 --- a/src/generate/device.rs +++ b/src/generate/device.rs @@ -6,9 +6,10 @@ use log::debug; use std::borrow::Cow; use std::fs::File; use std::io::Write; +use std::path::Path; -use crate::util::{self, Config, ToSanitizedCase}; -use crate::Target; +use crate::config::{Config, Target}; +use crate::util::{self, ToSanitizedCase}; use anyhow::{Context, Result}; use crate::generate::{interrupt, peripheral}; @@ -139,7 +140,13 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result Result { }) } -/// Load a [Device](svd::Device) from a string slice with given [config](crate::util::Config). -pub fn load_from(input: &str, config: &crate::util::Config) -> Result { - use self::util::SourceType; +/// Load a [Device](svd::Device) from a string slice with given [config](crate::config::Config). +pub fn load_from(input: &str, config: &Config) -> Result { + use config::SourceType; use svd_parser::ValidateLevel; let mut device = match config.source_type { diff --git a/src/main.rs b/src/main.rs index fc989fb2..8151f20f 100755 --- a/src/main.rs +++ b/src/main.rs @@ -2,16 +2,17 @@ use log::{debug, error, info}; -use std::fs::File; use std::io::Write; use std::process; +use std::{fs::File, path::Path}; use anyhow::{Context, Result}; use clap::{Arg, ArgAction, Command}; use svd2rust::{ + config::{Config, SourceType, Target}, generate, load_from, - util::{self, build_rs, Config, SourceType, Target}, + util::{self, build_rs}, }; fn parse_configs(app: Command) -> Result { @@ -216,7 +217,7 @@ fn run() -> Result<()> { if let Some(file) = config.input.as_ref() { config.source_type = SourceType::from_path(file) } - let path = &config.output_dir; + let path = config.output_dir.as_deref().unwrap_or(Path::new(".")); info!("Parsing device from SVD file"); let device = load_from(input, &config)?; diff --git a/src/util.rs b/src/util.rs index 4be04689..722a24cb 100644 --- a/src/util.rs +++ b/src/util.rs @@ -6,14 +6,13 @@ use inflections::Inflect; use proc_macro2::{Ident, Span, TokenStream}; use quote::quote; use std::collections::HashSet; -use std::path::{Path, PathBuf}; use svd_rs::{MaybeArray, Peripheral, PeripheralInfo}; use syn::{ punctuated::Punctuated, token::PathSep, Lit, LitInt, PathArguments, PathSegment, Type, TypePath, }; -use anyhow::{anyhow, bail, Result}; +use anyhow::{anyhow, Result}; pub const BITS_PER_BYTE: u32 = 8; @@ -21,53 +20,6 @@ pub const BITS_PER_BYTE: u32 = 8; /// that are not valid in Rust ident const BLACKLIST_CHARS: &[char] = &['(', ')', '[', ']', '/', ' ', '-']; -#[cfg_attr(feature = "serde", derive(serde::Deserialize))] -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct Config { - #[cfg_attr(feature = "serde", serde(default))] - pub target: Target, - #[cfg_attr(feature = "serde", serde(default))] - pub atomics: bool, - #[cfg_attr(feature = "serde", serde(default))] - pub atomics_feature: Option, - #[cfg_attr(feature = "serde", serde(default))] - pub generic_mod: bool, - #[cfg_attr(feature = "serde", serde(default))] - pub make_mod: bool, - #[cfg_attr(feature = "serde", serde(default))] - pub ignore_groups: bool, - #[cfg_attr(feature = "serde", serde(default))] - pub keep_list: bool, - #[cfg_attr(feature = "serde", serde(default))] - pub strict: bool, - #[cfg_attr(feature = "serde", serde(default))] - pub pascal_enum_values: bool, - #[cfg_attr(feature = "serde", serde(default))] - pub feature_group: bool, - #[cfg_attr(feature = "serde", serde(default))] - pub feature_peripheral: bool, - #[cfg_attr(feature = "serde", serde(default))] - pub max_cluster_size: bool, - #[cfg_attr(feature = "serde", serde(default))] - pub impl_debug: bool, - #[cfg_attr(feature = "serde", serde(default))] - pub impl_debug_feature: Option, - #[cfg_attr(feature = "serde", serde(default = "current_dir"))] - pub output_dir: PathBuf, - #[cfg_attr(feature = "serde", serde(default))] - pub input: Option, - #[cfg_attr(feature = "serde", serde(default))] - pub source_type: SourceType, - #[cfg_attr(feature = "serde", serde(default))] - pub log_level: Option, - #[cfg_attr(feature = "serde", serde(default))] - pub interrupt_link_section: Option, - #[cfg_attr(feature = "serde", serde(default))] - pub reexport_core_peripherals: bool, - #[cfg_attr(feature = "serde", serde(default))] - pub reexport_interrupt: bool, -} - #[derive(Clone, Debug, PartialEq, Eq)] pub enum Case { Constant, @@ -103,107 +55,6 @@ impl Case { } } -fn current_dir() -> PathBuf { - PathBuf::from(".") -} - -impl Default for Config { - fn default() -> Self { - Self { - target: Target::default(), - atomics: false, - atomics_feature: None, - generic_mod: false, - make_mod: false, - ignore_groups: false, - keep_list: false, - strict: false, - pascal_enum_values: false, - feature_group: false, - feature_peripheral: false, - max_cluster_size: false, - impl_debug: false, - impl_debug_feature: None, - output_dir: current_dir(), - input: None, - source_type: SourceType::default(), - log_level: None, - interrupt_link_section: None, - reexport_core_peripherals: false, - reexport_interrupt: false, - } - } -} - -#[allow(clippy::upper_case_acronyms)] -#[allow(non_camel_case_types)] -#[cfg_attr(feature = "serde", derive(serde::Deserialize))] -#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)] -pub enum Target { - #[cfg_attr(feature = "serde", serde(rename = "cortex-m"))] - #[default] - CortexM, - #[cfg_attr(feature = "serde", serde(rename = "msp430"))] - Msp430, - #[cfg_attr(feature = "serde", serde(rename = "riscv"))] - RISCV, - #[cfg_attr(feature = "serde", serde(rename = "xtensa-lx"))] - XtensaLX, - #[cfg_attr(feature = "serde", serde(rename = "mips"))] - Mips, - #[cfg_attr(feature = "serde", serde(rename = "none"))] - None, -} - -impl Target { - pub fn parse(s: &str) -> Result { - Ok(match s { - "cortex-m" => Target::CortexM, - "msp430" => Target::Msp430, - "riscv" => Target::RISCV, - "xtensa-lx" => Target::XtensaLX, - "mips" => Target::Mips, - "none" => Target::None, - _ => bail!("unknown target {}", s), - }) - } -} - -#[cfg_attr( - feature = "serde", - derive(serde::Deserialize), - serde(rename_all = "lowercase") -)] -#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)] -pub enum SourceType { - #[default] - Xml, - #[cfg(feature = "yaml")] - Yaml, - #[cfg(feature = "json")] - Json, -} - -impl SourceType { - /// Make a new [`SourceType`] from a given extension. - pub fn from_extension(s: &str) -> Option { - match s { - "svd" | "xml" => Some(Self::Xml), - #[cfg(feature = "yaml")] - "yml" | "yaml" => Some(Self::Yaml), - #[cfg(feature = "json")] - "json" => Some(Self::Json), - _ => None, - } - } - pub fn from_path(path: &Path) -> Self { - path.extension() - .and_then(|e| e.to_str()) - .and_then(Self::from_extension) - .unwrap_or_default() - } -} - /// Convert self string into specific case without overlapping to svd2rust internal names pub trait ToSanitizedCase { /// Convert self into PascalCase.