1
2use std::collections::HashMap;
3use std::io::Read;
4use std::io::Seek;
5use std::path::Path;
6use std::sync::Arc;
7use std::sync::RwLock;
8use derive_builder::Builder;
9
10pub use crate::models::*;
11pub use crate::io::*;
12
13#[derive(Clone, Builder)]
14#[builder(setter(strip_option, into))]
15pub struct GdsLibrary {
16 #[builder(default)]
17 pub version: i16,
18 pub create_date: GdsDateTime,
19 pub modify_date: GdsDateTime,
20 pub name: String,
21
22 pub usrunits_per_dbunit: f64,
26 pub meters_per_dbunit: f64,
30
31 #[builder(default)]
32 pub reflibs: Option<[String; 2]>,
33 #[builder(default)]
34 pub fonts: Option<[String; 4]>,
35 #[builder(default)]
36 pub attrtable: Option<String>,
37 #[builder(default)]
38 pub generations: Option<i16>,
39 #[builder(default)]
40 pub format: Option<GdsFormat>,
41
42 #[builder(default)]
43 pub structures: HashMap<String, Arc<RwLock<GdsStructure>>>,
44}
45
46impl GdsLibrary {
47 pub fn new(name: impl Into<String>) -> Self {
48 GdsLibraryBuilder::default()
49 .name(name)
50 .create_date(GdsDateTime::now())
51 .modify_date(GdsDateTime::now())
52 .version(0i16)
53 .usrunits_per_dbunit(0.001)
54 .meters_per_dbunit(1e-9)
55 .build()
56 .unwrap()
57 }
58
59 pub fn with_version(&mut self, version: i16) {
60 self.version = version;
61 }
62
63 pub fn usrunits_per_dbunit(&mut self, value: f64) {
64 self.usrunits_per_dbunit = value;
65 }
66
67 pub fn meters_per_dbunit(&mut self, value: f64) {
68 self.meters_per_dbunit = value;
69 }
70
71 pub fn new_structure(&mut self, name: impl Into<String>) -> Arc<RwLock<GdsStructure>> {
72 let name = name.into();
73 let structure = Arc::new(RwLock::new(GdsStructure::new(name.clone())));
74 self.structures.insert(name, structure.clone());
75 structure
76 }
77
78 pub fn add_structure(&mut self, structure: Arc<RwLock<GdsStructure>>) {
79 let name = structure.read().unwrap().name.clone();
80 self.structures.insert(name, structure);
81 }
82
83 pub fn dbuint_to_micro(&self, uint: i32) -> f64 {
84 let ratio = 1. / (self.meters_per_dbunit * 1e6);
85 uint as f64 / ratio
86 }
87
88 pub fn micro_to_dbunit(&self, micro: f64) -> i32 {
89 let ratio = 1. / (self.meters_per_dbunit * 1e6);
90 f64::round(micro * ratio) as i32
91 }
92
93 pub fn structure_size(&self) -> usize {
94 self.structures.len()
95 }
96}
97
98impl GdsLibrary {
99 pub fn load_file<P: AsRef<Path>>(path: P) -> GdsReadResult<Self> {
100 let mut reader = GdsReader::open(path)?;
101 reader.read()
102 }
103
104 pub fn save_gds_file<P: AsRef<Path>>(&self, path: P) -> GdsWriteResult<()> {
105 let mut writer = GdsWriter::open(path)?;
106 writer.write(self)
107 }
108
109 pub fn save_text_file<P: AsRef<Path>>(&self, path: P) -> GdsWriteResult<()> {
110 let mut writer = TextWriter::open(path)?;
111 writer.write(self)
112 }
113
114 pub fn read<R: Read + Seek>(reader: R) -> GdsReadResult<Self> {
115 let mut reader = GdsReader::new(reader)?;
116 reader.read()
117 }
118
119 pub fn write_gds<W: std::io::Write>(&self, writer: W) -> GdsWriteResult<()> {
120 let mut writer = GdsWriter::new(writer);
121 writer.write(self)
122 }
123
124 pub fn write_text<W: std::io::Write>(&self, writer: W) -> GdsWriteResult<()> {
125 let mut writer = TextWriter::new(writer);
126 writer.write(self)
127 }
128}