Expand description
Reading EnergyML data stores behind one abstraction: an EPC file today, an ETP v1.2 dataspace later.
§The shape, in one paragraph
EnergymlStorage is the mother trait, and it is drawn after the ETP
protocol, not after a zip file - addressing by URI, plural operations,
partial responses. An EPC fits inside that shape (a file is a dataspace);
the reverse would not have been true. EpcStore implements it, and also
carries a complete synchronous API so that an application which only
reads local files never has to write async. The reasoning is in
ADR-0002.
use std::sync::Arc;
use energyml_core::registry::Registry;
use energyml_storage::EpcStore;
let mut registry = Registry::new();
// energyml_resqml_2_0_1::register(&mut registry); - the application chooses
// which versions it knows: nothing is hard-wired here.
let store = EpcStore::open("model.epc", Arc::new(registry))?;
for summary in store.resources() {
let header = store.header(&summary.uri)?;
println!("{} - {}", header.summary.qualified_type, header.display_name());
}§Three levels, and a listing needs all three
| Level | Call | What it opens |
|---|---|---|
| identity | EpcStore::resources | the package index only |
| citation | EpcStore::header | the first bytes of the part |
| object | EpcStore::get_object | the whole part |
An interface listing a two-gigabyte EPC lives at level 2, and getting there cheaply is the point of the split.
§Tolerant, and never silent
Real packages break the specification. This reader accepts what it can and
records every departure as a Diagnostic - the same rule the code
generator follows for the schema constructs it cannot map: nothing is lost
in silence.
§Writing
An open package is modifiable: EpcStore::edit hands out a borrow and
marks the object, EpcStore::put and EpcStore::remove add and delete,
and nothing touches the archive until EpcStore::save. Saving does not
patch the old package, it rebuilds one - [Content_Types].xml, every
.rels in both directions, docProps/core.xml - because a description that
no longer matches is worse than none. Transactions are one more layer of the
same in-memory stack, so a rollback really undoes.
§External arrays
An object points at its numbers; it does not hold them. EpcStore finds
every pointer, in both the spellings EnergyML uses, and reads them through
an ArrayBackend. HDF5 is one, behind the optional hdf5 feature -
without it an EPC is still read, edited and written, and only reading an
array fails, saying which capability is missing rather than pretending the
data is absent. A WebAssembly application supplies its own backend over
h5wasm and nothing here changes.
Re-exports§
pub use array::ArrayBuffer;pub use array::ArrayData;pub use array::ArrayLocation;pub use array::ArrayMetadata;pub use array::ArrayValues;pub use array::NoProxies;pub use array::ProxyResolver;pub use array::ProxyTarget;pub use array::Resolution;pub use backend::ArrayBackend;pub use backend::Backends;pub use backend::Candidate;pub use backend::ExternalFiles;pub use backend::Origin;pub use capabilities::Capabilities;pub use capabilities::EdgeKindCoverage;pub use capabilities::StoreTimes;pub use changes::EnergymlChanges;pub use context::Context;pub use context::DeletedFilter;pub use context::DeletedResource;pub use context::Found;pub use context::Scope;pub use dataspaces::EnergymlDataspaces;pub use epc::overlay::SavePolicy;pub use epc::EpcStore;pub use epc::SaveOptions;pub use epc::Unreadable;pub use error::Diagnostic;pub use error::Error;pub use error::ExternalDataReason;pub use error::Result;pub use error::Severity;pub use graph::Edge;pub use graph::EdgeKind;pub use graph::RefIssue;pub use graph::RefIssueKind;pub use kinds::Judged;pub use kinds::KindBasis;pub use kinds::KindRules;pub use kinds::StandardRules;pub use raw::RawFormat;pub use raw::RawObject;pub use rename::Applied as Renamed;pub use rename::FileMove;pub use rename::Rename;pub use resource::ActiveStatus;pub use resource::CustomValue;pub use resource::Dataspace;pub use resource::ObjectHeader;pub use resource::ObjectSummary;pub use resource::Relationship;pub use storage::Contents;pub use storage::EnergymlStorage;pub use storage::LocalPackage;pub use write::EnergymlWriter;pub use write::Put;pub use write::Transaction;pub use write::TransactionRequest;
Modules§
- array
- Finding, and later reading, the arrays that live outside the package.
- backend
- Where the numbers come from, behind one trait.
- capabilities
- What a store can do, said before it is asked.
- changes
- What changed since a reader last looked: the shape of a change feed.
- context
- Which objects a request reaches: ETP’s
ContextInfoandContextScopeKind. - dataspaces
- The level above one dataspace: ETP’s Dataspace protocol (24).
- epc
- Reading an EPC file.
- error
- What can go wrong, and what merely looks odd.
- extract
- Taking a chosen set of objects out of a package, and saying what that cost.
- graph
- Checking that the references inside a package point somewhere.
- import
- Bringing part of another package into the open one: a quote, then the writing. Bringing part of another package - or all of it - into the one that is open.
- kinds
- The kind of an edge, primary or secondary, and what each answer rests on. The kind of an edge, primary or secondary, and where each answer comes from.
- raw
- An object as bytes, the way it travels: ETP’s
DataObject. - relabel
- Changing what a part declares itself to be, without parsing what it holds. Changing what a part says it is, without reading what it holds.
- rename
- Renaming the external data file a package points at.
- resource
- What a store knows about an object before it reads it.
- search
- Finding objects by what a person remembers of them: a type, a title, a bare uuid.
- storage
- The mother trait, shaped after ETP.
- window
- Reading a bounded window of an array, with the statistics of what was read.
- write
- The writing half of the storage interface, shaped after ETP like the reading half.