sbol/lib.rs
1//! Rust support for the Synthetic Biology Open Language (SBOL) 3.1.0
2//! specification.
3//!
4//! The crate keeps RDF parsing and serialization behind a small adapter while
5//! exposing SBOL documents, typed builders, owned typed client objects, and
6//! structured validation diagnostics.
7//!
8//! ```
9//! use sbol::constants::SBO_DNA;
10//! use sbol::prelude::*;
11//!
12//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
13//! let component = Component::builder("https://example.org/lab", "my_component")?
14//! .types([SBO_DNA])
15//! .name("My component")
16//! .build()?;
17//!
18//! let document = Document::from_objects(vec![SbolObject::Component(component)])?;
19//! document.check()?;
20//!
21//! assert_eq!(document.components().count(), 1);
22//! # Ok(())
23//! # }
24//! ```
25//!
26//! # Mental model
27//!
28//! SBOL describes designed biology as a graph of typed objects. Every object
29//! has a stable [`Iri`] identity, a `displayId`, and a namespace. Objects
30//! split into two layers:
31//!
32//! - **Top-level objects** live directly in a [`Document`]:
33//! [`Component`] (the central design unit — DNA, RNA, protein, complexes,
34//! functional descriptions), [`Sequence`], [`Collection`],
35//! [`CombinatorialDerivation`], [`Implementation`], [`ExperimentalData`],
36//! [`Experiment`], [`Model`], [`Attachment`], plus PROV-O activities
37//! ([`Activity`], [`Plan`], [`Agent`]) and OM unit definitions ([`Unit`]
38//! and friends).
39//! - **Owned children** belong to a top-level parent and live nested inside
40//! it: [`SubComponent`] / [`LocalSubComponent`] /
41//! [`ExternallyDefined`] / [`SequenceFeature`] / [`ComponentReference`]
42//! hang off [`Component`]; [`Range`] / [`Cut`] / [`EntireSequence`] hang
43//! off features; [`Interaction`]s contain [`Participation`]s;
44//! [`Constraint`]s relate features.
45//!
46//! References between objects are typed: a [`SubComponent`] names the
47//! [`Component`] it instantiates, an [`ExternallyDefined`] points to a term in
48//! an external ontology, and so on. Reference traversal lives on the typed
49//! structs and takes anything implementing [`ObjectGraph`] — a [`Document`]
50//! for single-file work, a [`DocumentSet`] when references cross document
51//! boundaries.
52//!
53//! # Document lifecycle
54//!
55//! A typical flow:
56//!
57//! 1. **Read.** [`Document::read_path`] infers the format from the file
58//! extension; [`Document::read`] takes an explicit [`RdfFormat`] for
59//! in-memory input.
60//! 2. **Validate.** [`Document::validate`] returns a full
61//! [`ValidationReport`] with errors, warnings, and per-rule coverage —
62//! use it when you want to inspect or render the report regardless of
63//! pass/fail state. [`Document::check`] is the `?`-friendly convenience
64//! that maps errors to `Err` (warnings ignored), and
65//! [`Document::check_complete`] additionally fails on
66//! partial-application diagnostics for strict CI gates.
67//! 3. **Traverse / mutate.** Typed accessors on [`Document`] iterate each
68//! top-level class (`document.components()`, `document.sequences()`,
69//! `document.activities()`, …). Builders ([`Component::builder`], etc.)
70//! construct new objects without invalidating existing IRIs.
71//! 4. **Write.** [`Document::write`] takes an [`RdfFormat`];
72//! `write_turtle`, `write_rdf_xml`, `write_jsonld`, and `write_ntriples`
73//! are shortcut methods. Round-trip preserves unknown extension triples.
74//!
75//! # Error model
76//!
77//! Errors are surfaced through four distinct types so callers can branch on
78//! the failure mode without parsing strings:
79//!
80//! - [`ReadError`] — I/O or parse failure when ingesting RDF.
81//! - [`BuildError`] — invariant violation at builder time (invalid
82//! `displayId`, malformed namespace, missing required field).
83//! - [`WriteError`] — serialization failure.
84//! - [`ValidationReport`] — structured diagnostics from validation
85//! (multiple issues per call, each with its `sbol3-*` rule identifier).
86//!
87//! # Where to go next
88//!
89//! - **[Crate guide](https://github.com/marpaia/sbol-rs/blob/master/docs/crate-guide.md)** —
90//! architectural tour and where each subsystem lives.
91//! - **[Validation system overview](https://github.com/marpaia/sbol-rs/blob/master/docs/validation.md)** —
92//! what the validator covers, `check` vs `check_complete`, CI wiring,
93//! trust boundaries.
94//! - **[RDF I/O](https://github.com/marpaia/sbol-rs/blob/master/docs/rdf-io.md)** —
95//! format inference, round-trip guarantees, cross-implementation
96//! conformance.
97//! - **[Conformance grid](https://github.com/marpaia/sbol-rs/blob/master/docs/conformance.md)** —
98//! generated per-rule status for every SBOL 3.1.0 rule.
99//! - **[`prelude`]** — re-exports the symbols you'll need for most code;
100//! `use sbol::prelude::*;` is the conventional import. It includes the
101//! [`SbolIdentified`] and [`SbolTopLevel`] accessor traits so methods
102//! like `component.name()`, `component.display_id()`, and
103//! `component.namespace()` are available on every typed object.
104//! - **[`constants`]** — IRIs for SBO / SO / EDAM / SBOL terms that show up
105//! as builder arguments (`SBO_DNA`, `SO_PROMOTER`, etc.).
106
107#![forbid(unsafe_code)]
108// `check`/`check_complete` deliberately return the full ValidationReport in
109// both Ok and Err arms so callers always get the report; boxing the Err arm
110// would split that surface.
111#![allow(clippy::result_large_err)]
112
113mod client;
114mod conformance;
115pub mod constants;
116mod document;
117pub mod downgrade;
118mod error;
119pub mod identity;
120mod iri_util;
121mod model;
122mod object;
123pub mod owl_conformance;
124pub mod prelude;
125mod resolve;
126mod sbol2_vocab;
127pub mod schema;
128mod specification;
129pub mod upgrade;
130mod validation;
131mod vocab;
132
133pub use client::{
134 Activity, ActivityBuilder, Agent, AgentBuilder, Association, AssociationBuilder, Attachment,
135 AttachmentBuilder, BinaryPrefix, BinaryPrefixBuilder, Collection, CollectionBuilder,
136 CombinatorialDerivation, CombinatorialDerivationBuilder, Component, ComponentBuilder,
137 ComponentReference, ComponentReferenceBuilder, CompoundUnit, CompoundUnitBuilder, Constraint,
138 ConstraintBuilder, Cut, CutBuilder, EntireSequence, EntireSequenceBuilder, Experiment,
139 ExperimentBuilder, ExperimentalData, ExperimentalDataBuilder, ExtensionTriple,
140 ExternallyDefined, ExternallyDefinedBuilder, FeatureData, FeatureRef, IdentifiedData,
141 IdentifiedExtension, IdentifiedExtensionBuilder, Implementation, ImplementationBuilder,
142 Interaction, InteractionBuilder, Interface, InterfaceBuilder, LocalSubComponent,
143 LocalSubComponentBuilder, LocationData, LocationRef, Measure, MeasureBuilder, Model,
144 ModelBuilder, Participation, ParticipationBuilder, Plan, PlanBuilder, Prefix, PrefixBuilder,
145 PrefixData, PrefixedUnit, PrefixedUnitBuilder, Range, RangeBuilder, SIPrefix, SIPrefixBuilder,
146 SbolIdentified, SbolObject, SbolTopLevel, Sequence, SequenceBuilder, SequenceFeature,
147 SequenceFeatureBuilder, SingularUnit, SingularUnitBuilder, SubComponent, SubComponentBuilder,
148 ToRdf, TopLevelData, TryFromObject, Unit, UnitBuilder, UnitData, UnitDivision,
149 UnitDivisionBuilder, UnitExponentiation, UnitExponentiationBuilder, UnitMultiplication,
150 UnitMultiplicationBuilder, Usage, UsageBuilder, VariableFeature, VariableFeatureBuilder,
151};
152pub use conformance::render_conformance_report;
153pub use document::{Document, UpgradeFromPathError};
154pub use downgrade::{
155 DowngradeCounts, DowngradeError, DowngradeOptions, DowngradeReport, DowngradeWarning,
156 sbol3_to_sbol2,
157};
158pub use error::{BuildError, ReadError, WriteError};
159pub use identity::{DisplayId, HashAlgorithm, Namespace, SbolIdentity, SequenceElements};
160pub use model::{Identified, SbolClass, TopLevel};
161pub use object::Object;
162pub use owl_conformance::{
163 OWL_ONLY_ALLOWLIST, OwlConformanceReport, OwlIdentifiers, OwlPinInfo, RUST_ONLY_ALLOWLIST,
164 analyze_owl_conformance, extract_owl_identifiers, extract_vocab_iris,
165 render_owl_conformance_report,
166};
167pub use resolve::{FeatureTrace, ObjectGraph, ReferenceError, VariantSet};
168pub use sbol_ontology::{Ontology, OntologyRegistry};
169pub use sbol_rdf::{Graph as RdfGraph, Iri, Literal, RdfFormat, Resource, Term, Triple};
170pub use specification::{SPEC_VERSION, SPECIFICATION_URL};
171pub use upgrade::{
172 MapsToSide, NamespaceSource, UpgradeCounts, UpgradeError, UpgradeOptions, UpgradeReport,
173 UpgradeWarning, parse_and_upgrade, sbol2_to_sbol3,
174};
175#[cfg(feature = "http-resolver")]
176pub use validation::CachingHttpResolver;
177#[cfg(feature = "http-resolver")]
178pub use validation::HttpResolver;
179pub use validation::{
180 AppliedOptions, Blocker, ContentResolver, CoverageKind, DocumentResolver, DocumentSet,
181 DocumentSetError, ExternalValidationMode, FileResolver, HashAlgorithmRegistry, Hint,
182 NormativeSeverity, NotApplied, NotAppliedReason, PartialApplication, PolicyOptions,
183 ResolutionError, ResolutionErrorKind, ResolvedContent, RuleCoverage, RuleOverride, RuleStatus,
184 Severity, TopologyCompleteness, UnknownRule, VALIDATION_OUTPUT_SCHEMA_VERSION,
185 VALIDATION_RULE_SPEC_CANONICAL_URL, VALIDATION_RULE_SPEC_PATH, VALIDATION_RULE_SPEC_PDF_SHA256,
186 VALIDATION_RULE_SPEC_VERSION, ValidationContext, ValidationIssue, ValidationOptions,
187 ValidationReport, ValidationRuleStatus, to_json, validation_rule_statuses,
188};