klayout_core/
properties.rs1use smol_str::SmolStr;
7
8#[derive(Clone, Debug, PartialEq)]
9pub enum PropertyValue {
10 Int(i64),
11 Float(f64),
12 String(SmolStr),
13 Bytes(Vec<u8>),
14 List(Vec<PropertyValue>),
15}
16
17impl Eq for PropertyValue {}
18
19impl std::hash::Hash for PropertyValue {
20 fn hash<H: std::hash::Hasher>(&self, h: &mut H) {
21 match self {
22 PropertyValue::Int(i) => {
23 h.write_u8(0);
24 i.hash(h);
25 }
26 PropertyValue::Float(f) => {
27 h.write_u8(1);
28 h.write_u64(f.to_bits());
29 }
30 PropertyValue::String(s) => {
31 h.write_u8(2);
32 s.hash(h);
33 }
34 PropertyValue::Bytes(b) => {
35 h.write_u8(3);
36 b.hash(h);
37 }
38 PropertyValue::List(l) => {
39 h.write_u8(4);
40 l.hash(h);
41 }
42 }
43 }
44}
45
46#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
47pub struct Properties {
48 inner: Vec<(SmolStr, PropertyValue)>,
49}
50
51impl Properties {
52 pub fn new() -> Self {
53 Self::default()
54 }
55
56 pub fn is_empty(&self) -> bool {
57 self.inner.is_empty()
58 }
59
60 pub fn len(&self) -> usize {
61 self.inner.len()
62 }
63
64 pub fn set(&mut self, key: impl Into<SmolStr>, value: PropertyValue) {
65 let key = key.into();
66 if let Some(slot) = self.inner.iter_mut().find(|(k, _)| *k == key) {
67 slot.1 = value;
68 } else {
69 self.inner.push((key, value));
70 }
71 }
72
73 pub fn get(&self, key: &str) -> Option<&PropertyValue> {
74 self.inner.iter().find(|(k, _)| k == key).map(|(_, v)| v)
75 }
76
77 pub fn iter(&self) -> impl Iterator<Item = (&SmolStr, &PropertyValue)> {
78 self.inner.iter().map(|(k, v)| (k, v))
79 }
80
81 pub(crate) fn sorted_iter(&self) -> Vec<(&SmolStr, &PropertyValue)> {
82 let mut v: Vec<_> = self.inner.iter().map(|(k, v)| (k, v)).collect();
83 v.sort_by(|a, b| a.0.cmp(b.0));
84 v
85 }
86}