Skip to content

Commit b64c075

Browse files
authored
Make pcb-sch round-trip deserializable (#258)
* Make InstanceRef deserializable * fix panic * default
1 parent da4cdbd commit b64c075

File tree

1 file changed

+32
-2
lines changed

1 file changed

+32
-2
lines changed

crates/pcb-sch/src/lib.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ impl ModuleRef {
7676
}
7777

7878
#[derive(Debug, Clone, Serialize, Deserialize, Eq)]
79-
#[serde(into = "String")] // serialise using Display impl (string path)
79+
#[serde(into = "String", try_from = "String")] // serialize and deserialize using string format
8080
pub struct InstanceRef {
8181
/// Reference to the root module this instance belongs to.
8282
pub module: ModuleRef,
@@ -139,6 +139,36 @@ impl From<InstanceRef> for String {
139139
}
140140
}
141141

142+
impl std::str::FromStr for InstanceRef {
143+
type Err = String;
144+
145+
fn from_str(s: &str) -> Result<Self, Self::Err> {
146+
// Parse format: "path/to/file.zen:module_name.instance.path"
147+
let (module_part, instance_path_str) = s
148+
.split_once(':')
149+
.ok_or_else(|| format!("Invalid InstanceRef format: missing ':' in '{}'", s))?;
150+
151+
let parts: Vec<&str> = instance_path_str.split('.').collect();
152+
if parts.is_empty() {
153+
return Err(format!("Invalid InstanceRef: no module name in '{}'", s));
154+
}
155+
156+
let module_name = parts[0];
157+
let instance_path: Vec<Symbol> = parts[1..].iter().map(|&p| p.into()).collect();
158+
159+
let module_ref = ModuleRef::new(PathBuf::from(module_part), Symbol::from(module_name));
160+
Ok(InstanceRef::new(module_ref, instance_path))
161+
}
162+
}
163+
164+
impl TryFrom<String> for InstanceRef {
165+
type Error = String;
166+
167+
fn try_from(s: String) -> Result<Self, Self::Error> {
168+
s.parse()
169+
}
170+
}
171+
142172
/// Discriminates the *kind* of an [`Instance`].
143173
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
144174
pub enum InstanceKind {
@@ -306,7 +336,7 @@ pub struct Instance {
306336
pub attributes: HashMap<Symbol, AttributeValue>,
307337
pub children: HashMap<Symbol, InstanceRef>,
308338
pub reference_designator: Option<String>,
309-
#[serde(skip_serializing_if = "HashMap::is_empty")]
339+
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
310340
pub symbol_positions: HashMap<String, Position>,
311341
}
312342

0 commit comments

Comments
 (0)