Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use Rc<str> instead of String in pathes #264

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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, ops::Deref, 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.deref() != part1 {
return false;
}
for p in parts.zip(self.path.iter()) {
if p.0 != p.1 {
if p.0 != p.1.deref() {
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.deref() == 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.deref() == 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.deref() == 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.deref());
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.deref());
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.deref());
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.deref()), evs);
}
}
self.fields.insert(fpath, f);
}
}
let fpath = path.new_field(&f.name);
let fpath = path.new_field(f.name.deref());
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.deref()), 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.deref()));

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.deref()));

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.deref()));

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.deref()), 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.deref()));
if let Some(regs) = p.registers.as_mut() {
for rc in take(regs) {
expand_register_cluster(regs, rc, &path, &index)?;
Expand Down