Skip to content

Commit

Permalink
use Arc<str> instead of String in pathes
Browse files Browse the repository at this point in the history
  • Loading branch information
burrbull committed Aug 22, 2024
1 parent 6464100 commit 2aed203
Showing 1 changed file with 34 additions and 36 deletions.
70 changes: 34 additions & 36 deletions svd-parser/src/expand.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
//! Provides [expand] method to convert arrays, clusters and derived items in regular instances
use anyhow::{anyhow, Result};
use std::collections::HashMap;
use std::fmt;
use std::mem::take;
use std::{collections::HashMap, fmt, mem::take, rc::Rc};
use svd_rs::{
array::names, cluster, field, peripheral, register, Cluster, ClusterInfo, DeriveFrom, Device,
EnumeratedValues, Field, Peripheral, Register, RegisterCluster, RegisterProperties,
Expand All @@ -12,23 +10,23 @@ use svd_rs::{
/// Path to `peripheral` or `cluster` element
#[derive(Clone, Debug, PartialEq, Hash, Eq)]
pub struct BlockPath {
pub peripheral: String,
pub path: Vec<String>,
pub peripheral: Rc<str>,
pub path: Vec<Rc<str>>,
}

impl BlockPath {
pub fn new(p: impl Into<String>) -> Self {
pub fn new(p: impl Into<Rc<str>>) -> Self {
Self {
peripheral: p.into(),
path: Vec::new(),
}
}
pub fn new_cluster(&self, name: impl Into<String>) -> Self {
pub fn new_cluster(&self, name: impl Into<Rc<str>>) -> Self {
let mut child = self.clone();
child.path.push(name.into());
child
}
pub fn new_register(&self, name: impl Into<String>) -> RegisterPath {
pub fn new_register(&self, name: impl Into<Rc<str>>) -> RegisterPath {
RegisterPath::new(self.clone(), name)
}
pub fn parse_str(s: &str) -> (Option<Self>, &str) {
Expand All @@ -46,7 +44,7 @@ impl BlockPath {
};
(block, name)
}
pub fn name(&self) -> &String {
pub fn name(&self) -> &str {
self.path.last().unwrap()
}
pub fn parent(&self) -> Option<Self> {
Expand All @@ -63,11 +61,11 @@ impl PartialEq<str> for BlockPath {
}
let mut parts = other.split('.');
if let Some(part1) = parts.next() {
if self.peripheral != part1 {
if self.peripheral.as_ref() != part1 {
return false;
}
for p in parts.zip(self.path.iter()) {
if p.0 != p.1 {
if p.0 != p.1.as_ref() {
return false;
}
}
Expand All @@ -93,17 +91,17 @@ impl fmt::Display for BlockPath {
#[derive(Clone, Debug, PartialEq, Hash, Eq)]
pub struct RegisterPath {
pub block: BlockPath,
pub name: String,
pub name: Rc<str>,
}

impl RegisterPath {
pub fn new(block: BlockPath, name: impl Into<String>) -> Self {
pub fn new(block: BlockPath, name: impl Into<Rc<str>>) -> Self {
Self {
block,
name: name.into(),
}
}
pub fn new_field(&self, name: impl Into<String>) -> FieldPath {
pub fn new_field(&self, name: impl Into<Rc<str>>) -> FieldPath {
FieldPath::new(self.clone(), name)
}
pub fn parse_str(s: &str) -> (Option<BlockPath>, &str) {
Expand All @@ -112,15 +110,15 @@ impl RegisterPath {
pub fn parse_vec(v: Vec<&str>) -> (Option<BlockPath>, &str) {
BlockPath::parse_vec(v)
}
pub fn peripheral(&self) -> &String {
pub fn peripheral(&self) -> &str {
&self.block.peripheral
}
}

impl PartialEq<str> for RegisterPath {
fn eq(&self, other: &str) -> bool {
if let Some((block, reg)) = other.rsplit_once('.') {
self.name == reg && &self.block == block
self.name.as_ref() == reg && &self.block == block
} else {
false
}
Expand All @@ -140,17 +138,17 @@ impl fmt::Display for RegisterPath {
#[derive(Clone, Debug, PartialEq, Hash, Eq)]
pub struct FieldPath {
pub register: RegisterPath,
pub name: String,
pub name: Rc<str>,
}

impl FieldPath {
pub fn new(register: RegisterPath, name: impl Into<String>) -> Self {
pub fn new(register: RegisterPath, name: impl Into<Rc<str>>) -> Self {
Self {
register,
name: name.into(),
}
}
pub fn new_enum(&self, name: impl Into<String>) -> EnumPath {
pub fn new_enum(&self, name: impl Into<Rc<str>>) -> EnumPath {
EnumPath::new(self.clone(), name)
}
pub fn parse_str(s: &str) -> (Option<RegisterPath>, &str) {
Expand All @@ -172,15 +170,15 @@ impl FieldPath {
pub fn register(&self) -> &RegisterPath {
&self.register
}
pub fn peripheral(&self) -> &String {
pub fn peripheral(&self) -> &str {
self.register.peripheral()
}
}

impl PartialEq<str> for FieldPath {
fn eq(&self, other: &str) -> bool {
if let Some((reg, field)) = other.rsplit_once('.') {
self.name == field && &self.register == reg
self.name.as_ref() == field && &self.register == reg
} else {
false
}
Expand All @@ -200,11 +198,11 @@ impl fmt::Display for FieldPath {
#[derive(Clone, Debug, PartialEq, Hash, Eq)]
pub struct EnumPath {
pub field: FieldPath,
pub name: String,
pub name: Rc<str>,
}

impl EnumPath {
pub fn new(field: FieldPath, name: impl Into<String>) -> Self {
pub fn new(field: FieldPath, name: impl Into<Rc<str>>) -> Self {
Self {
field,
name: name.into(),
Expand All @@ -216,15 +214,15 @@ impl EnumPath {
pub fn register(&self) -> &RegisterPath {
&self.field.register
}
pub fn peripheral(&self) -> &String {
pub fn peripheral(&self) -> &str {
self.field.peripheral()
}
}

impl PartialEq<str> for EnumPath {
fn eq(&self, other: &str) -> bool {
if let Some((field, evs)) = other.rsplit_once('.') {
self.name == evs && &self.field == field
self.name.as_ref() == evs && &self.field == field
} else {
false
}
Expand Down Expand Up @@ -263,7 +261,7 @@ impl<'a> Index<'a> {
self.peripherals.insert(path, p);
}
}
let path = BlockPath::new(&p.name);
let path = BlockPath::new(p.name.as_ref());
for r in p.registers() {
self.add_register(&path, r);
}
Expand All @@ -286,7 +284,7 @@ impl<'a> Index<'a> {
self.clusters.insert(cpath, c);
}
}
let cpath = path.new_cluster(&c.name);
let cpath = path.new_cluster(c.name.as_ref());
for r in c.registers() {
self.add_register(&cpath, r);
}
Expand All @@ -305,7 +303,7 @@ impl<'a> Index<'a> {
self.registers.insert(rpath, r);
}
}
let rpath = path.new_register(&r.name);
let rpath = path.new_register(r.name.as_ref());
for f in r.fields() {
self.add_field(&rpath, f);
}
Expand All @@ -317,16 +315,16 @@ impl<'a> Index<'a> {
let fpath = path.new_field(name);
for evs in &f.enumerated_values {
if let Some(name) = evs.name.as_ref() {
self.evs.insert(fpath.new_enum(name), evs);
self.evs.insert(fpath.new_enum(name.as_ref()), evs);
}
}
self.fields.insert(fpath, f);
}
}
let fpath = path.new_field(&f.name);
let fpath = path.new_field(f.name.as_ref());
for evs in &f.enumerated_values {
if let Some(name) = evs.name.as_ref() {
self.evs.insert(fpath.new_enum(name), evs);
self.evs.insert(fpath.new_enum(name.as_ref()), evs);
}
}
self.fields.insert(fpath, f);
Expand Down Expand Up @@ -365,7 +363,7 @@ fn expand_cluster_array(
if let Some(dpath) = dpath {
cpath = derive_cluster(&mut c, &dpath, path, index)?;
}
let cpath = cpath.unwrap_or_else(|| path.new_cluster(&c.name));
let cpath = cpath.unwrap_or_else(|| path.new_cluster(c.name.as_ref()));

for rc in take(&mut c.children) {
expand_register_cluster(&mut c.children, rc, &cpath, index)?;
Expand Down Expand Up @@ -499,7 +497,7 @@ fn expand_register_array(
if let Some(dpath) = dpath {
rpath = derive_register(&mut r, &dpath, path, index)?;
}
let rpath = rpath.unwrap_or_else(|| path.new_register(&r.name));
let rpath = rpath.unwrap_or_else(|| path.new_register(r.name.as_ref()));

if let Some(field) = r.fields.as_mut() {
for f in take(field) {
Expand Down Expand Up @@ -529,7 +527,7 @@ fn expand_field(
if let Some(dpath) = dpath {
fpath = derive_field(&mut f, &dpath, rpath, index)?;
}
let fpath = fpath.unwrap_or_else(|| rpath.new_field(&f.name));
let fpath = fpath.unwrap_or_else(|| rpath.new_field(f.name.as_ref()));

for ev in &mut f.enumerated_values {
let dpath = ev.derived_from.take();
Expand Down Expand Up @@ -564,7 +562,7 @@ pub fn derive_enumerated_values(
if let Some(r) = index.registers.get(rdpath) {
let mut found = None;
for f in r.fields() {
let epath = EnumPath::new(rdpath.new_field(&f.name), dname);
let epath = EnumPath::new(rdpath.new_field(f.name.as_ref()), dname);
if let Some(d) = index.evs.get(&epath) {
found = Some((d, epath));
break;
Expand Down Expand Up @@ -645,7 +643,7 @@ pub fn expand(indevice: &Device) -> Result<Device> {
if let Some(dpath) = dpath {
path = derive_peripheral(&mut p, &dpath, &index)?;
}
let path = path.unwrap_or_else(|| BlockPath::new(&p.name));
let path = path.unwrap_or_else(|| BlockPath::new(p.name.as_ref()));
if let Some(regs) = p.registers.as_mut() {
for rc in take(regs) {
expand_register_cluster(regs, rc, &path, &index)?;
Expand Down

0 comments on commit 2aed203

Please sign in to comment.