|
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