3 releases (breaking)
Uses old Rust 2015
0.3.0 | Jul 17, 2018 |
---|---|
0.2.0 | Jun 26, 2018 |
0.1.0 | Apr 2, 2018 |
#50 in #release
70KB
1K
SLoC
rust_release_channel: a data structure for Rust release channel metadata
Repository: https://gitlab.com/Screwtapello/rust_release_channel/
Documentation: https://docs.rs/rust_release_channel
TODO
- Store hashes as bytes rather than hex-encoded bytes?
- might make it easier to compare with the results of other hash functions
- make
impl Display for Channel
format as TOML, instead of the current human-readable output? That way we can replace our custom.to_string()
method with the actualToString
trait, which might be less surprising.
lib.rs
:
A data structure for Rust release channel metadata
Introduction
New versions of the Rust toolchain are released on a regular six-week cycle. Each version is described in a release-channel metadata file in a known location, allowing automated tools to detect new releases and find the tools and components for each supported platform.
The data structures in this library represent the information present in each metadata file, organised to help you pull out the specific information you need.
This library is designed to handle version 2 of the manifest file format.
The most important class is Channel
,
so you'll want to start there.
First Example
extern crate rust_release_channel;
use std::error::Error;
fn dump_manifest_info(input: &str) -> Result<(), Box<Error>> {
// Parse the manifest into a data structure.
let channel: rust_release_channel::Channel = input.parse()?;
// Check the manifest is sensible before we use it.
let errors = channel.validate();
if errors.is_empty() {
// Dump a summary of the manifest data
println!(
"Channel manifest created on {}",
channel.date,
);
println!("Included packages:");
for (name, pkg) in channel.pkg.iter() {
println!(" - {} version {}", name, pkg.version);
}
} else {
println!("Channel has problems:");
for each in errors {
println!(" - {}", each);
}
}
Ok(())
}
Capabilities
Reading manifests
If you can read the content of an existing manifest file,
you can turn it into a queryable, explorable data structure
with the .parse()
method
(courtesy of the standard FromStr
trait).
# extern crate rust_release_channel;
# use std::error::Error;
# fn example1() -> Result<(), Box<Error>> {
# let my_str = r#"metadata-version = "2"\ndate = "2018-02-26"\n"#;
use rust_release_channel::Channel;
let channel: Channel = my_str.parse()?;
# Ok(())
# }
After reading a manifest,
you should call .validate()
to see if the data makes sense before trusting it.
Querying manifests
All the content of the manifest is available to inspect,
as native-feeling Rust data structures.
For example,
where the native manifest file-format models
different available file-formats as
differently-named keys with the same meaning
(url
vs. xz_url
, hash
vs. xz_hash
),
rust_release_channel
gives you a mapping from
ArchiveFormat
to ArchiveSource
.
# extern crate rust_release_channel;
# use std::error::Error;
# fn example2() -> Result<(), Box<Error>> {
# let my_str = r#"metadata-version = "2"\ndate = "2018-02-26"\n"#;
# let channel: rust_release_channel::Channel = my_str.parse()?;
use rust_release_channel::{ArtefactQuery, ArchiveFormat};
let rust_for_aarch64_url = channel.lookup_artefact(
ArtefactQuery::new("rust", "aarch64-unknown-linux-gnu"),
)
.and_then(|artefact| {
artefact.standalone.get(&ArchiveFormat::TarGzip)
})
.map(|archive| { &archive.url });
# Ok(())
# }
Creating fresh manifests
You can also create manifest data completely from scratch, in case you need to create test-data for another system.
# extern crate rust_release_channel;
# extern crate chrono;
# use std::error::Error;
# fn example3() -> Result<(), Box<Error>> {
use rust_release_channel::{
Channel,
Package,
Artefact,
ArchiveFormat,
ArchiveSource,
};
let source = ArchiveSource::new(
"https://example.com/rust/mypackage-linux-x86.tar.gz".parse()?,
"aa0a89d80329fec6f9e84b79c1674c5427034408630c35da1be442c7da6d2364"
.into(),
);
let mut artefact = Artefact::new();
artefact.standalone.insert(ArchiveFormat::TarGzip, source);
let mut mypackage = Package::new("1.2.3 (abc1234 2018-02-26)".into());
mypackage.target.insert("x86_64-unknown-linux-gnu".into(), artefact);
let mut channel = Channel::new();
channel.pkg.insert("mypackage".into(), mypackage);
# Ok(())
# }
Writing manifests
You can turn manifest data back into a string with the .to_string()
method.
If you serialize a Channel
and deserialize it again,
the result should be identical to the original.
# extern crate rust_release_channel;
# use std::error::Error;
# fn example3() -> Result<(), Box<Error>> {
# let channel = rust_release_channel::Channel::new();
let manifest_string = channel.to_string()?;
# Ok(())
# }
Before writing a manifest,
you should call .validate()
to check you haven't left the metadata in an inconsistent state.
Dependencies
~2.6–3.5MB
~93K SLoC