liberty_db/
lib.rs

1//! This crate implement `liberty` data structre in Rust.
2//!
3//! Demo:
4//! ``` rust
5//! use liberty_db::{DefaultCtx, Library, MutSetExt, PinId};
6//! use std::{
7//!   fs::File,
8//!   io::{BufWriter, Write},
9//! };
10//! static TEMPLATE: &str = r#"
11//! library(demo) {
12//!   time_unit : "1ps";
13//!   voltage_unit : "10mV";
14//!   current_unit : "1uA";
15//!   operating_conditions ( typical ) {
16//!       process : 1;
17//!       voltage : 1.1;
18//!   }
19//!   lu_table_template(delay_template_4x5) {
20//!     variable_1 : total_output_net_capacitance;
21//!     variable_2 : input_net_transition;
22//!     index_1 ("1000.0, 1001.0, 1002.0, 1003.0");
23//!     index_2 ("1000.0, 1001.0, 1002.0, 1003.0, 1004.0");
24//!   }
25//!   cell (DFF) {
26//!     pin (D) {}
27//!     pin (CK) {}
28//!     pin (Q) {}
29//!   }
30//! }"#;
31//! let mut library = Library::<DefaultCtx>::parse_lib(TEMPLATE, None).unwrap();
32//! // modify library
33//! library.cell.get_mut("DFF").map(|cell_dff| {
34//!   cell_dff
35//!     .pin
36//!     .get_mut(&PinId::from("CK"))
37//!     .map(|pin_ck| pin_ck.clock = Some(true))
38//! });
39//! // print library
40//! println!("{library}");
41//! // write library
42//! let out_file = File::create("demo.lib").unwrap();
43//! let mut writer = BufWriter::new(out_file);
44//! write!(&mut writer, "{}", library).unwrap();
45//! ```
46//! <script>
47//! IFRAME('https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html');
48//! </script>
49#![doc(
50    // The following are document setting according to
51    // https://doc.rust-lang.org/rustdoc/write-documentation/the-doc-attribute.html
52    // For html-pdf-viewer setting:
53    // https://tinytip.co/tips/html-pdf-params/
54    // html_favicon_url = "https://example.com/favicon.ico",
55    // html_logo_url = "https://example.com/logo.jpg",
56    html_playground_url = "https://play.rust-lang.org",
57)]
58// #![cfg_attr(
59//     feature = "nightly",
60//     feature(
61//         test,
62//         core_intrinsics,
63//         dropck_eyepatch,
64//         min_specialization,
65//         extend_one,
66//         allocator_api,
67//         slice_ptr_get,
68//         nonnull_slice_from_raw_parts,
69//         maybe_uninit_array_assume_init,
70//         build_hasher_simple_hash_one
71//     )
72// )]
73#![deny(
74    // The following are allowed by default lints according to
75    // https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html
76    anonymous_parameters,
77    bare_trait_objects,
78    // box_pointers,
79    elided_lifetimes_in_paths, // allow anonymous lifetime
80    missing_debug_implementations,
81    // missing_docs, // TODO: add documents
82    // trivial_casts, // TODO: remove trivial casts in code
83    trivial_numeric_casts,
84    // unsafe_code,
85    unstable_features,
86    unused_extern_crates,
87    unused_import_braces,
88    unreachable_pub, // allow clippy::redundant_pub_crate lint instead
89    // unused_qualifications,
90    unused_results, // TODO: fix unused results
91    variant_size_differences,
92    // warnings, // treat all wanings as errors
93    clippy::all,
94    clippy::restriction,
95    clippy::pedantic,
96    clippy::nursery,
97    clippy::cargo
98)]
99#![allow(
100    // Some explicitly allowed Clippy lints, must have clear reason to allow
101    clippy::arbitrary_source_item_ordering,
102    clippy::allow_attributes_without_reason,
103    clippy::default_numeric_fallback,
104    clippy::pattern_type_mismatch, // TODO: 
105    clippy::too_long_first_doc_paragraph,
106    clippy::partial_pub_fields,
107    clippy::single_char_lifetime_names,
108    clippy::while_let_on_iterator,
109    clippy::iter_over_hash_type,
110    clippy::separated_literal_suffix,
111    clippy::single_call_fn,
112    clippy::pub_use,
113    clippy::or_fun_call,
114    clippy::pub_with_shorthand,
115    clippy::ignored_unit_patterns,
116    clippy::mod_module_files,
117    clippy::todo,
118    clippy::unreachable,
119    clippy::missing_trait_methods,
120    clippy::min_ident_chars,
121    clippy::missing_docs_in_private_items,
122    clippy::blanket_clippy_restriction_lints, // allow clippy::restriction
123    clippy::implicit_return, // actually omitting the return keyword is idiomatic Rust code
124    clippy::module_name_repetitions, // repeation of module name in a struct name is not big deal
125    clippy::multiple_crate_versions, // multi-version dependency crates is not able to fix
126    clippy::panic, // allow debug_assert, panic in production code
127    clippy::panic_in_result_fn,
128    clippy::missing_errors_doc, // TODO: add error docs
129    clippy::exhaustive_structs,
130    clippy::exhaustive_enums,
131    clippy::missing_panics_doc, // TODO: add panic docs
132    clippy::print_stdout,
133    clippy::absolute_paths,
134    clippy::use_debug,
135    clippy::question_mark_used,
136    clippy::used_underscore_binding,
137)]
138#![warn(
139    clippy::manual_map,
140    clippy::shadow_reuse,
141    clippy::option_if_let_else,
142    clippy::wildcard_enum_match_arm,
143    clippy::needless_return,
144    clippy::same_name_method,
145    clippy::missing_inline_in_public_items,
146    clippy::doc_markdown,
147    dead_code,
148    missing_copy_implementations, // Copy may cause unnecessary memory copy
149    // missing_docs,
150    // single_use_lifetimes, // TODO: fix lifetime names only used once
151    unused_qualifications,
152)]
153#![cfg_attr(
154  test,
155  allow(
156    dead_code,
157    unused,
158    unused_imports,
159    unused_results,
160    clippy::trivially_copy_pass_by_ref,
161    clippy::shadow_unrelated,
162    clippy::default_numeric_fallback,
163    clippy::unreadable_literal,
164    clippy::type_complexity,
165    clippy::unwrap_used,
166    clippy::expect_used,
167    clippy::too_many_lines,
168    clippy::float_arithmetic,
169    clippy::non_ascii_literal,
170    clippy::must_use_candidate,
171    clippy::needless_raw_strings,
172    clippy::cast_possible_truncation,
173    clippy::as_conversions,
174    clippy::needless_raw_string_hashes,
175    clippy::indexing_slicing,
176    clippy::arithmetic_side_effects,
177    clippy::field_reassign_with_default,
178    clippy::undocumented_unsafe_blocks,
179    clippy::or_fun_call,
180  )
181)]
182#[expect(unused_imports)]
183#[cfg(not(feature = "tracing"))]
184use log::{debug, error, info, trace, warn};
185#[expect(unused_imports)]
186#[cfg(feature = "tracing")]
187use tracing::{debug, error, info, trace, warn};
188
189#[cfg(any(feature = "lut_template", feature = "py"))]
190extern crate alloc;
191pub use biodivine_lib_bdd;
192pub use strum::IntoEnumIterator;
193/// `cell` group structure.
194pub mod cell;
195pub use cell::Cell;
196/// Common items/miscs.
197pub mod common;
198/// `Boolean Expression`, `SDF Expression`, and so on.
199pub mod expression;
200/// `internal_power` group structure.
201pub mod internal_power;
202pub use internal_power::{InternalPower, InternalPowerId};
203/// `Library` group structure, top level of liberty format.
204pub mod library;
205/// `table` group structure.
206pub mod table;
207pub use library::Library;
208// pub mod str;
209// pub use str::LibertyStr;
210/// `pin` group structure.
211pub mod pin;
212pub use pin::{Pin, PinId};
213/// `timing` group structure.
214pub mod timing;
215pub use timing::{Timing, TimingId};
216#[cfg(feature = "py")]
217mod py;
218pub mod units;
219pub use mut_set::{Item, MutSetExt};
220
221pub mod ast;
222pub use ast::Group;
223
224/// CCSN relative attributes
225pub mod ccsn;
226mod ctx;
227pub use ctx::{Ctx, DefaultCtx};
228
229#[cfg(test)]
230#[test]
231fn demo() {
232  use crate::{DefaultCtx, Library, MutSetExt as _, PinId};
233  use std::{
234    fs::File,
235    io::{BufWriter, Write as _},
236  };
237  static TEMPLATE: &str = r#"
238library(demo) {
239  time_unit : "1ps";
240  voltage_unit : "10mV";
241  current_unit : "1uA";
242  operating_conditions ( typical ) {
243      process : 1;
244      voltage : 1.1;
245  }
246  lu_table_template(delay_template_4x5) {
247    variable_1 : total_output_net_capacitance;
248    variable_2 : input_net_transition;
249    index_1 ("1000.0, 1001.0, 1002.0, 1003.0");
250    index_2 ("1000.0, 1001.0, 1002.0, 1003.0, 1004.0");
251  }
252  cell (DFF) {
253    pin (D) {}
254    pin (CK) {}
255    pin (Q) {}
256  }
257}"#;
258  let mut library = Library::<DefaultCtx>::parse_lib(TEMPLATE, None).unwrap();
259  // modify library
260  library.cell.get_mut("DFF").map(|cell_dff| {
261    cell_dff
262      .pin
263      .get_mut(&PinId::from("CK"))
264      .map(|pin_ck| pin_ck.clock = Some(true))
265  });
266  // print library
267  println!("{library}");
268  // write library
269  let out_file = File::create("demo.lib").unwrap();
270  let mut writer = BufWriter::new(out_file);
271  write!(&mut writer, "{library}").unwrap();
272}