| 
1 | 1 | use anyhow::{bail, Result};  | 
 | 2 | +use proc_macro2::Span;  | 
2 | 3 | use std::{  | 
3 | 4 |     collections::HashMap,  | 
4 | 5 |     ops::{Deref, DerefMut},  | 
5 | 6 |     path::{Path, PathBuf},  | 
 | 7 | +    str::FromStr,  | 
6 | 8 | };  | 
 | 9 | +use syn::{punctuated::Punctuated, Ident};  | 
 | 10 | + | 
 | 11 | +use crate::util::path_segment;  | 
7 | 12 | 
 
  | 
8 | 13 | #[cfg_attr(feature = "serde", derive(serde::Deserialize), serde(default))]  | 
9 | 14 | #[derive(Clone, PartialEq, Eq, Debug, Default)]  | 
@@ -35,9 +40,10 @@ pub struct Config {  | 
35 | 40 |     pub ident_formats_theme: Option<IdentFormatsTheme>,  | 
36 | 41 |     pub field_names_for_enums: bool,  | 
37 | 42 |     pub base_address_shift: u64,  | 
38 |  | -    pub html_url: Option<url::Url>,  | 
39 | 43 |     /// Path to YAML file with chip-specific settings  | 
40 |  | -    pub settings: Option<PathBuf>,  | 
 | 44 | +    pub settings_file: Option<PathBuf>,  | 
 | 45 | +    /// Chip-specific settings  | 
 | 46 | +    pub settings: Settings,  | 
41 | 47 | }  | 
42 | 48 | 
 
  | 
43 | 49 | #[allow(clippy::upper_case_acronyms)]  | 
@@ -320,8 +326,57 @@ pub enum IdentFormatsTheme {  | 
320 | 326 | #[non_exhaustive]  | 
321 | 327 | /// Chip-specific settings  | 
322 | 328 | pub struct Settings {  | 
 | 329 | +    /// Path to chip HTML generated by svdtools  | 
 | 330 | +    pub html_url: Option<url::Url>,  | 
 | 331 | +    pub crate_path: Option<CratePath>,  | 
323 | 332 |     /// RISC-V specific settings  | 
324 | 333 |     pub riscv_config: Option<riscv::RiscvConfig>,  | 
325 | 334 | }  | 
326 | 335 | 
 
  | 
 | 336 | +impl Settings {  | 
 | 337 | +    pub fn update_from(&mut self, source: Self) {  | 
 | 338 | +        if source.html_url.is_some() {  | 
 | 339 | +            self.html_url = source.html_url;  | 
 | 340 | +        }  | 
 | 341 | +        if source.crate_path.is_some() {  | 
 | 342 | +            self.crate_path = source.crate_path;  | 
 | 343 | +        }  | 
 | 344 | +        if source.riscv_config.is_some() {  | 
 | 345 | +            self.riscv_config = source.riscv_config;  | 
 | 346 | +        }  | 
 | 347 | +    }  | 
 | 348 | +}  | 
 | 349 | + | 
 | 350 | +#[derive(Clone, PartialEq, Eq, Debug)]  | 
 | 351 | +pub struct CratePath(pub syn::Path);  | 
 | 352 | + | 
 | 353 | +impl Default for CratePath {  | 
 | 354 | +    fn default() -> Self {  | 
 | 355 | +        let mut segments = Punctuated::new();  | 
 | 356 | +        segments.push(path_segment(Ident::new("crate", Span::call_site())));  | 
 | 357 | +        Self(syn::Path {  | 
 | 358 | +            leading_colon: None,  | 
 | 359 | +            segments,  | 
 | 360 | +        })  | 
 | 361 | +    }  | 
 | 362 | +}  | 
 | 363 | + | 
 | 364 | +#[cfg(feature = "serde")]  | 
 | 365 | +impl<'de> serde::Deserialize<'de> for CratePath {  | 
 | 366 | +    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>  | 
 | 367 | +    where  | 
 | 368 | +        D: serde::Deserializer<'de>,  | 
 | 369 | +    {  | 
 | 370 | +        let s = String::deserialize(deserializer)?;  | 
 | 371 | +        Ok(Self::from_str(&s).unwrap())  | 
 | 372 | +    }  | 
 | 373 | +}  | 
 | 374 | + | 
 | 375 | +impl FromStr for CratePath {  | 
 | 376 | +    type Err = syn::Error;  | 
 | 377 | +    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {  | 
 | 378 | +        syn::parse_str(&s).map(Self)  | 
 | 379 | +    }  | 
 | 380 | +}  | 
 | 381 | + | 
327 | 382 | pub mod riscv;  | 
0 commit comments