webc/lib.rs
1//! A library for reading and writing WEBC files.
2//!
3//! The [`Container`] provides an abstraction over the various WEBC versions
4//! this crate can handle. As such, it tries to cater to the lowest common
5//! denominator and favors portability over performance or power.
6//!
7//! ```rust,no_run
8//! use webc::{Container, Version};
9//! let bytes: &[u8] = b"\0webc...";
10//!
11//! let container = Container::from_bytes_and_version(bytes.into(), Version::V3)?;
12//!
13//! println!("{:?}", container.manifest());
14//!
15//! println!("Atoms:");
16//! for (name, atom) in container.atoms() {
17//! let length = atom.len();
18//! println!("{name}: {length} bytes");
19//! }
20//!
21//! for (name, volume) in container.volumes() {
22//! let root_items = volume.read_dir("/").expect("The root directory always exists");
23//! println!("{name}: {} items", root_items.len());
24//! }
25//! # Ok::<(), Box<dyn std::error::Error>>(())
26//! ```
27//!
28//! In general, errors that occur during lazy operations won't be accessible to
29//! the user.
30//!
31//! # Version-Specific Fallbacks
32//!
33//! If more flexibility is required, consider using [`crate::detect()`] and
34//! instantiating a compatible parser directly.
35//!
36//! ```rust,no_run
37//! use webc::{
38//! Container,
39//! Version,
40//! };
41//! # #[cfg(feature = "v1")]
42//! use webc::v1::{ParseOptions, WebC};
43//! # #[cfg(feature = "v3")]
44//! use webc::v3::read::OwnedReader;
45//! let bytes: &[u8] = b"...";
46//!
47//! match webc::detect(bytes) {
48//! # #[cfg(feature = "v1")]
49//! Ok(Version::V1) => {
50//! let options = ParseOptions::default();
51//! let webc = WebC::parse(bytes, &options).unwrap();
52//! if let Some(signature) = webc.signature {
53//! println!("Package signature: {:?}", signature);
54//! }
55//! }
56//! # #[cfg(feature = "v3")]
57//! Ok(Version::V3) => {
58//! let webc = OwnedReader::parse(bytes).unwrap();
59//! let index = webc.index();
60//! let signature = &index.signature;
61//! if !signature.is_none() {
62//! println!("Package signature: {signature:?}");
63//! }
64//! }
65//! Ok(other) => todo!("Unsupported version, {other}"),
66//! Err(e) => todo!("An error occurred: {e}"),
67//! }
68//! ```
69//!
70//! # Feature Flags
71//!
72#![doc = document_features::document_features!()]
73#![warn(unreachable_pub, elided_lifetimes_in_paths)]
74#![deny(missing_docs, missing_debug_implementations)]
75#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
76
77pub extern crate bytes;
78pub extern crate indexmap;
79
80#[cfg(test)]
81#[macro_use]
82extern crate pretty_assertions;
83
84#[cfg(test)]
85#[macro_use]
86#[allow(dead_code, unused_macros)]
87mod macros;
88
89mod container;
90mod detect;
91mod from_path_with_ignore;
92pub mod metadata;
93mod path_segments;
94mod readable_bytes;
95mod timestamps;
96mod utils;
97#[allow(missing_docs)]
98#[cfg(feature = "v1")]
99pub mod v1;
100#[cfg(feature = "v2")]
101pub mod v2;
102#[cfg(feature = "v3")]
103pub mod v3;
104
105#[cfg(all(feature = "v2", feature = "v3"))]
106pub mod migration;
107
108mod version;
109mod volume;
110
111/// The type for [`MAGIC`].
112pub type Magic = [u8; 5];
113
114/// File identification bytes stored at the beginning of the file.
115pub const MAGIC: Magic = *b"\0webc";
116
117pub use crate::{
118 container::{Container, ContainerError},
119 detect::{detect, is_webc, DetectError},
120 from_path_with_ignore::DirectoryFromPathError,
121 path_segments::{PathSegment, PathSegmentError, PathSegments, ToPathSegments},
122 timestamps::Timestamps,
123 utils::sanitize_path,
124 version::Version,
125 volume::{AbstractVolume, Metadata, Volume, VolumeError},
126};
127
128pub(crate) use timestamps::since_epoch;
129
130#[doc(hidden)] // HACK: Made accessible for wasmer-cli. Not for public use.
131pub use crate::container::{AbstractWebc, AsAny};
132
133/// A compatibility layer for dealing with different versions of the WEBC binary
134/// format.
135#[deprecated(since = "5.1.0", note = "Import types directly from the crate")]
136pub mod compat {
137 pub use crate::{
138 container::{Container, ContainerError},
139 volume::{Metadata, Volume, VolumeError},
140 };
141
142 #[deprecated = "Use shared_buffer::OwnedBuffer directly"]
143 pub use shared_buffer::OwnedBuffer as SharedBytes;
144}