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

Add a basic CLI for debugging #41

Merged
merged 1 commit into from
May 2, 2024
Merged
Show file tree
Hide file tree
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
87 changes: 86 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ resolver = "2"
members = [
"altium",
"altium-macros",
"ecad-cli",
"ecadg",
# "drawsvg",
]
4 changes: 2 additions & 2 deletions altium/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ num_enum = "0.7.2"
quick-xml = "0.31.0"
regex = "1.10.4"
rust-ini = "0.21.0"
serde = "1.0.200"
serde = { version = "1.0.200", features = ["derive"] }
serde-xml-rs = "0.6.0"
svg = "0.17.0"
uom = "0.36.0"
uuid = { version = "1.8.0", features = ["v1", "v4", "fast-rng"]}
uuid = { version = "1.8.0", features = ["v1", "v4", "fast-rng", "serde"]}
xml-rs = "0.8.20"

[dev-dependencies]
Expand Down
45 changes: 38 additions & 7 deletions altium/src/common.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::{fmt, str};

use num_traits::CheckedMul;
use serde::{Deserialize, Serialize};
use uuid::Uuid;

use crate::error::{AddContext, ErrorKind, Result, TruncBuf};
Expand All @@ -11,15 +12,15 @@ const SEP: u8 = b'|';
const KV_SEP: u8 = b'=';

/// Common coordinate type with x and y positions in nnaometers.
#[derive(Clone, Copy, Debug, Default, PartialEq)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct Location {
// These are nonpublic because we might want to combine `Location` and `LocationFract`
pub(crate) x: i32,
pub(crate) y: i32,
}

/// Location with fraction
#[derive(Clone, Copy, Debug, Default, PartialEq)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct LocationFract {
pub x: i32,
pub x_fract: i32,
Expand Down Expand Up @@ -60,6 +61,17 @@ impl Location {
}
}

impl LocationFract {
/// Sometimes we don't want to deal with fractions
#[inline]
pub fn as_location(self) -> Location {
Location {
x: self.x,
y: self.y,
}
}
}

impl From<(i32, i32)> for Location {
fn from(value: (i32, i32)) -> Self {
Self {
Expand All @@ -69,7 +81,7 @@ impl From<(i32, i32)> for Location {
}
}

#[derive(Clone, Copy, Debug, Default, PartialEq)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize)]
pub enum Visibility {
Hidden,
#[default]
Expand All @@ -86,9 +98,11 @@ impl FromUtf8<'_> for Visibility {
///
/// Every entity in Altium has a unique ID including files, library items, and records.
// TODO: figure out what file types use this exact format
#[derive(Clone, Copy, PartialEq)]
#[derive(Clone, Copy, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum UniqueId {
/// Altium's old style string unique ID
#[serde(with = "unique_id_serde")]
Simple([u8; 8]),
/// UUID style, used by some newer files
Uuid(Uuid),
Expand Down Expand Up @@ -139,6 +153,23 @@ impl FromUtf8<'_> for UniqueId {
}
}

mod unique_id_serde {
use serde::{de::Error, Deserialize, Deserializer, Serializer};

#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn serialize<S: Serializer>(val: &[u8; 8], serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(std::str::from_utf8(val).unwrap())
}

pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<[u8; 8], D::Error> {
// let s = <String>::deserialize(deserializer);
let s: &str = Deserialize::deserialize(deserializer)?;
s.as_bytes()
.try_into()
.map_err(|_| D::Error::custom(format!("expected a 8-byte unique ID; got '{s}'")))
}
}

/// Altium uses the format `Key1=Val1|Key2=Val2...`, this handles that
pub fn split_altium_map(buf: &[u8]) -> impl Iterator<Item = (&[u8], &[u8])> {
buf.split(|b| *b == SEP).filter(|x| !x.is_empty()).map(|x| {
Expand Down Expand Up @@ -169,7 +200,7 @@ pub fn str_from_utf8(buf: &[u8]) -> Result<&str, ErrorKind> {
}

/// RGB color
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct Rgb {
pub r: u8,
pub g: u8,
Expand Down Expand Up @@ -230,7 +261,7 @@ impl FromUtf8<'_> for Rgb {
}

/// Rotation when only 4 values are allowed
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum Rotation90 {
#[default]
R0 = 0,
Expand All @@ -256,7 +287,7 @@ impl FromUtf8<'_> for Rotation90 {
}
}

#[derive(Clone, Copy, Debug, Default, PartialEq)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize)]
pub enum ReadOnlyState {
#[default]
ReadWrite,
Expand Down
6 changes: 4 additions & 2 deletions altium/src/font.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

use std::ops::{Deref, DerefMut};

use serde::{Deserialize, Serialize};

lazy_static::lazy_static! {
pub(crate) static ref DEFAULT_FONT: Font = Font {
name: "Calibri".into(),
Expand All @@ -10,7 +12,7 @@ lazy_static::lazy_static! {
}

/// A font that is stored in a library
#[derive(Clone, Debug, Default, PartialEq)]
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct Font {
pub(crate) name: Box<str>,
pub(crate) size: u16,
Expand Down Expand Up @@ -41,7 +43,7 @@ impl Default for &Font {
//
// Or `Arc<RwLock<BTreeMap<u16, Arc<Font>>>>`. Yucky, but editable (edit the
// font if you're the only user duplicate it if you're not)
#[derive(Clone, Debug, Default, PartialEq)]
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct FontCollection(Vec<Font>);

impl FontCollection {
Expand Down
4 changes: 3 additions & 1 deletion altium/src/sch/params.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Parameter types stored in a schematic

use serde::{Deserialize, Serialize};

use crate::{
common::{PosHoriz, PosVert},
parse::{FromUtf8, ParseUtf8},
Expand Down Expand Up @@ -87,7 +89,7 @@ impl FromUtf8<'_> for SheetStyle {
}

/// Allowed text alignments in a schematic
#[derive(Clone, Copy, Debug, Default, PartialEq)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize)]
pub enum Justification {
#[default]
BottomLeft = 0,
Expand Down
7 changes: 4 additions & 3 deletions altium/src/sch/pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::str::{self, Utf8Error};

use altium_macros::FromRecord;
use log::warn;
use serde::{Deserialize, Serialize};

use super::SchRecord;
use crate::common::{mils_to_nm, Location, Rotation90, Visibility};
Expand All @@ -18,7 +19,7 @@ use crate::{ErrorKind, Result, UniqueId};
/// Altium stores pins as binary in the schematic libraries but text in the
/// schematic documents, so we need to parse both.
#[non_exhaustive]
#[derive(Clone, Debug, Default, PartialEq, FromRecord)]
#[derive(Clone, Debug, Default, PartialEq, FromRecord, Serialize, Deserialize)]
#[from_record(id = 2, record_variant = Pin)]
pub struct SchPin {
pub(super) formal_type: u8,
Expand Down Expand Up @@ -77,7 +78,7 @@ impl SchPin {
let (name, rest) = sized_buf_to_utf8(rest, "name")?;
let (designator, rest) = sized_buf_to_utf8(rest, "designator")?;

if !matches!(rest, [_, 0x03, b'|', b'&', b'|']) {
if !matches!(rest, [_, 0x03, b'|', b'&', b'|'] | [0x0, 0x0]) {
warn!("unexpected rest: {rest:02x?}");
}

Expand Down Expand Up @@ -175,7 +176,7 @@ fn get_rotation_and_hiding(val: u8) -> (Rotation90, Visibility, Visibility) {
}

#[repr(u8)]
#[derive(Clone, Copy, Default, Debug, PartialEq, Eq)]
#[derive(Clone, Copy, Default, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum ElectricalType {
#[default]
Input = 0,
Expand Down
Loading
Loading