Skip to content

Commit bc64f9c

Browse files
authored
Merge pull request #18 from EnzymeML/combine-archive
Add combine archive
2 parents 4760b12 + cd3a959 commit bc64f9c

29 files changed

+3419
-72
lines changed

Cargo.lock

Lines changed: 483 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@ crate-type = ["staticlib", "rlib"]
1717
autocxx = "0.28.0"
1818
cxx = "1.0.140"
1919
paste = "1.0.15"
20-
quick-xml = { version = "0.37.2", features = ["serialize"] }
20+
quick-xml = { version = "0.38.0", features = ["serialize"] }
2121
serde = { version = "1.0.217", features = ["derive"] }
2222
thiserror = "2.0.12"
23+
zip = "4.0.0"
2324

2425
[build-dependencies]
2526
autocxx-build = "0.28.0"
@@ -31,6 +32,7 @@ vcpkg = "0.2.15"
3132
[dev-dependencies]
3233
insta = "1.43.1"
3334
pretty_assertions = "1.4.1"
35+
tempfile = "3.20.0"
3436

3537
[lints.clippy]
3638
needless-lifetimes = "allow"

build.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ fn setup_vcpkg() -> Result<vcpkg::Library, BuilderError> {
126126
/// * `cargo_metadata` - A slice of strings containing cargo metadata directives
127127
fn link_lib(cargo_metadata: &[String]) {
128128
for metadata in cargo_metadata {
129-
println!("{}", metadata);
129+
println!("{metadata}");
130130
}
131131
}
132132

@@ -169,7 +169,7 @@ fn from_pkg_config(pkg_config: &str) -> Result<(Vec<PathBuf>, Vec<String>), Stri
169169

170170
let mut cargo_metadata = Vec::new();
171171
for lib in lib.libs {
172-
cargo_metadata.push(format!("cargo:rustc-link-lib={}", lib));
172+
cargo_metadata.push(format!("cargo:rustc-link-lib={lib}"));
173173
}
174174

175175
Ok((lib.include_paths.clone(), cargo_metadata))

examples/create.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use sbml::{prelude::*, unit::UnitKind};
1+
use sbml::{combine::KnownFormats, prelude::*, unit::UnitKind};
22

33
fn main() -> Result<(), Box<dyn std::error::Error>> {
44
let doc = SBMLDocument::default();
@@ -56,7 +56,24 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
5656
let sbml_string = doc.to_xml_string();
5757

5858
// Print the SBML string
59-
println!("{}", sbml_string);
59+
println!("{sbml_string}");
60+
61+
// Save as a string to a file
62+
std::fs::write("./model.xml", &sbml_string).expect("Failed to write file");
63+
64+
// Alternatively, save in a COMBINE archive
65+
let mut archive = CombineArchive::new();
66+
archive
67+
.add_entry(
68+
"./model.xml",
69+
KnownFormats::SBML,
70+
true,
71+
sbml_string.as_bytes(),
72+
)
73+
.expect("Failed to add entry to archive");
74+
archive
75+
.save("./model.omex")
76+
.expect("Failed to save archive");
6077

6178
Ok(())
6279
}

src/collections/compartments.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,52 @@ upcast_annotation!(
2929
sbmlcxx::ListOfCompartments,
3030
sbmlcxx::SBase
3131
);
32+
33+
#[cfg(test)]
34+
mod tests {
35+
use serde::{Deserialize, Serialize};
36+
37+
use crate::sbmldoc::SBMLDocument;
38+
39+
#[test]
40+
fn test_list_of_compartments_annotation_serde() {
41+
let doc = SBMLDocument::default();
42+
let model = doc.create_model("test");
43+
44+
#[derive(Serialize, Deserialize)]
45+
struct TestAnnotation {
46+
test: String,
47+
}
48+
49+
let annotation = TestAnnotation {
50+
test: "Test".to_string(),
51+
};
52+
53+
model
54+
.set_compartments_annotation_serde(&annotation)
55+
.unwrap();
56+
57+
let annotation: TestAnnotation = model.get_compartments_annotation_serde().unwrap();
58+
assert_eq!(annotation.test, "Test");
59+
}
60+
61+
#[test]
62+
fn test_list_of_compartments_annotation() {
63+
let doc = SBMLDocument::default();
64+
let model = doc.create_model("test");
65+
66+
let annotation = "<test>Test</test>";
67+
model
68+
.set_compartments_annotation(annotation)
69+
.expect("Failed to set annotation");
70+
71+
let annotation = model.get_compartments_annotation();
72+
assert_eq!(
73+
annotation
74+
.replace("\n", "")
75+
.replace("\r", "")
76+
.replace(" ", ""),
77+
"<annotation><test>Test</test></annotation>"
78+
);
79+
}
80+
}

src/collections/parameters.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,50 @@ upcast_annotation!(
2929
sbmlcxx::ListOfParameters,
3030
sbmlcxx::SBase
3131
);
32+
33+
#[cfg(test)]
34+
mod tests {
35+
use serde::{Deserialize, Serialize};
36+
37+
use crate::sbmldoc::SBMLDocument;
38+
39+
#[test]
40+
fn test_list_of_parameters_annotation_serde() {
41+
let doc = SBMLDocument::default();
42+
let model = doc.create_model("test");
43+
44+
#[derive(Serialize, Deserialize)]
45+
struct TestAnnotation {
46+
test: String,
47+
}
48+
49+
let annotation = TestAnnotation {
50+
test: "Test".to_string(),
51+
};
52+
53+
model.set_parameters_annotation_serde(&annotation).unwrap();
54+
55+
let annotation: TestAnnotation = model.get_parameters_annotation_serde().unwrap();
56+
assert_eq!(annotation.test, "Test");
57+
}
58+
59+
#[test]
60+
fn test_list_of_parameters_annotation() {
61+
let doc = SBMLDocument::default();
62+
let model = doc.create_model("test");
63+
64+
let annotation = "<test>Test</test>";
65+
model
66+
.set_parameters_annotation(annotation)
67+
.expect("Failed to set annotation");
68+
69+
let annotation = model.get_parameters_annotation();
70+
assert_eq!(
71+
annotation
72+
.replace("\n", "")
73+
.replace("\r", "")
74+
.replace(" ", ""),
75+
"<annotation><test>Test</test></annotation>"
76+
);
77+
}
78+
}

src/collections/reactions.rs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::{cell::RefCell, pin::Pin};
22

3-
use crate::{inner, model::Model, pin_ptr, sbmlcxx, upcast_annotation};
3+
use crate::{inner, model::Model, pin_ptr, sbase, sbmlcxx, upcast_annotation};
44

55
/// A safe wrapper around the libSBML ListOfReactions class.
66
///
@@ -24,8 +24,56 @@ impl<'a> ListOfReactions<'a> {
2424

2525
// Derive the inner type from the ListOfReactions type
2626
inner!(sbmlcxx::ListOfReactions, ListOfReactions<'a>);
27+
sbase!(ListOfReactions<'a>, sbmlcxx::ListOfReactions);
2728
upcast_annotation!(
2829
ListOfReactions<'a>,
2930
sbmlcxx::ListOfReactions,
3031
sbmlcxx::SBase
3132
);
33+
34+
#[cfg(test)]
35+
mod tests {
36+
use serde::{Deserialize, Serialize};
37+
38+
use crate::sbmldoc::SBMLDocument;
39+
40+
#[test]
41+
fn test_list_of_reactions_annotation_serde() {
42+
let doc = SBMLDocument::default();
43+
let model = doc.create_model("test");
44+
45+
#[derive(Serialize, Deserialize)]
46+
struct TestAnnotation {
47+
test: String,
48+
}
49+
50+
let annotation = TestAnnotation {
51+
test: "Test".to_string(),
52+
};
53+
54+
model.set_reactions_annotation_serde(&annotation).unwrap();
55+
56+
let annotation: TestAnnotation = model.get_reactions_annotation_serde().unwrap();
57+
assert_eq!(annotation.test, "Test");
58+
}
59+
60+
#[test]
61+
fn test_list_of_reactions_annotation() {
62+
let doc = SBMLDocument::default();
63+
let model = doc.create_model("test");
64+
65+
let annotation = "<test>Test</test>";
66+
model
67+
.set_reactions_annotation(annotation)
68+
.expect("Failed to set annotation");
69+
70+
let annotation = model.get_reactions_annotation();
71+
assert_eq!(
72+
annotation
73+
.replace("\n", "")
74+
.replace("\r", "")
75+
.replace(" ", ""),
76+
"<annotation><test>Test</test></annotation>"
77+
);
78+
}
79+
}

src/collections/rules.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,50 @@ impl<'a> ListOfRules<'a> {
2525
// Derive the inner type from the ListOfRules type
2626
inner!(sbmlcxx::ListOfRules, ListOfRules<'a>);
2727
upcast_annotation!(ListOfRules<'a>, sbmlcxx::ListOfRules, sbmlcxx::SBase);
28+
29+
#[cfg(test)]
30+
mod tests {
31+
use serde::{Deserialize, Serialize};
32+
33+
use crate::sbmldoc::SBMLDocument;
34+
35+
#[test]
36+
fn test_list_of_rules_annotation_serde() {
37+
let doc = SBMLDocument::default();
38+
let model = doc.create_model("test");
39+
40+
#[derive(Serialize, Deserialize)]
41+
struct TestAnnotation {
42+
test: String,
43+
}
44+
45+
let annotation = TestAnnotation {
46+
test: "Test".to_string(),
47+
};
48+
49+
model.set_rate_rules_annotation_serde(&annotation).unwrap();
50+
51+
let annotation: TestAnnotation = model.get_rate_rules_annotation_serde().unwrap();
52+
assert_eq!(annotation.test, "Test");
53+
}
54+
55+
#[test]
56+
fn test_list_of_rules_annotation() {
57+
let doc = SBMLDocument::default();
58+
let model = doc.create_model("test");
59+
60+
let annotation = "<test>Test</test>";
61+
model
62+
.set_rate_rules_annotation(annotation)
63+
.expect("Failed to set annotation");
64+
65+
let annotation = model.get_rate_rules_annotation();
66+
assert_eq!(
67+
annotation
68+
.replace("\n", "")
69+
.replace("\r", "")
70+
.replace(" ", ""),
71+
"<annotation><test>Test</test></annotation>"
72+
);
73+
}
74+
}

src/collections/species.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,50 @@ impl<'a> ListOfSpecies<'a> {
2525
// Derive the inner type from the ListOfSpecies type
2626
inner!(sbmlcxx::ListOfSpecies, ListOfSpecies<'a>);
2727
upcast_annotation!(ListOfSpecies<'a>, sbmlcxx::ListOfSpecies, sbmlcxx::SBase);
28+
29+
#[cfg(test)]
30+
mod tests {
31+
use serde::{Deserialize, Serialize};
32+
33+
use crate::sbmldoc::SBMLDocument;
34+
35+
#[test]
36+
fn test_list_of_species_annotation_serde() {
37+
let doc = SBMLDocument::default();
38+
let model = doc.create_model("test");
39+
40+
#[derive(Serialize, Deserialize)]
41+
struct TestAnnotation {
42+
test: String,
43+
}
44+
45+
let annotation = TestAnnotation {
46+
test: "Test".to_string(),
47+
};
48+
49+
model.set_species_annotation_serde(&annotation).unwrap();
50+
51+
let annotation: TestAnnotation = model.get_species_annotation_serde().unwrap();
52+
assert_eq!(annotation.test, "Test");
53+
}
54+
55+
#[test]
56+
fn test_list_of_species_annotation() {
57+
let doc = SBMLDocument::default();
58+
let model = doc.create_model("test");
59+
60+
let annotation = "<test>Test</test>";
61+
model
62+
.set_species_annotation(annotation)
63+
.expect("Failed to set annotation");
64+
65+
let annotation = model.get_species_annotation();
66+
assert_eq!(
67+
annotation
68+
.replace("\n", "")
69+
.replace("\r", "")
70+
.replace(" ", ""),
71+
"<annotation><test>Test</test></annotation>"
72+
);
73+
}
74+
}

src/collections/unitdefs.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,52 @@ upcast_annotation!(
3333
sbmlcxx::ListOfUnitDefinitions,
3434
sbmlcxx::SBase
3535
);
36+
37+
#[cfg(test)]
38+
mod tests {
39+
use serde::{Deserialize, Serialize};
40+
41+
use crate::sbmldoc::SBMLDocument;
42+
43+
#[test]
44+
fn test_list_of_unitdefs_annotation_serde() {
45+
let doc = SBMLDocument::default();
46+
let model = doc.create_model("test");
47+
48+
#[derive(Serialize, Deserialize)]
49+
struct TestAnnotation {
50+
test: String,
51+
}
52+
53+
let annotation = TestAnnotation {
54+
test: "Test".to_string(),
55+
};
56+
57+
model
58+
.set_unit_definitions_annotation_serde(&annotation)
59+
.unwrap();
60+
61+
let annotation: TestAnnotation = model.get_unit_definitions_annotation_serde().unwrap();
62+
assert_eq!(annotation.test, "Test");
63+
}
64+
65+
#[test]
66+
fn test_list_of_unitdefs_annotation() {
67+
let doc = SBMLDocument::default();
68+
let model = doc.create_model("test");
69+
70+
let annotation = "<test>Test</test>";
71+
model
72+
.set_unit_definitions_annotation(annotation)
73+
.expect("Failed to set annotation");
74+
75+
let annotation = model.get_unit_definitions_annotation();
76+
assert_eq!(
77+
annotation
78+
.replace("\n", "")
79+
.replace("\r", "")
80+
.replace(" ", ""),
81+
"<annotation><test>Test</test></annotation>"
82+
);
83+
}
84+
}

0 commit comments

Comments
 (0)