| Crates.io | hostlist_iter |
| lib.rs | hostlist_iter |
| version | 0.1.0 |
| created_at | 2025-04-30 05:42:49.20714+00 |
| updated_at | 2025-04-30 05:42:49.20714+00 |
| description | A hostlist handling library |
| homepage | |
| repository | https://github.com/mrepper/hostlist_iter |
| max_upload_size | |
| id | 1654472 |
| size | 98,735 |
A "hostlist" handling library with low memory footprint.
A hostlist is an expression representing a set of host names, commonly used in High Performance Computing (HPC) system applications. This library provides efficient parsing and manipulation of hostlist expressions with a minimal memory footprint.
Examples of hostlists and their equivalent host names:
node[1-3] == node1, node2, node3n[1-2]m[5-6] == n1m5, n1m6, n2m5, n2m6To add this crate to your project:
cargo add hostlist_iter
To install an optional CLI tool hostlist_iter:
cargo install hostlist_iter --features cli
Use the Hostlist type and iterate over it:
use hostlist_iter::Hostlist;
fn example() -> Result<(), hostlist_iter::Error> {
let hostlist: Hostlist = "node[1-3,5]".parse()?;
// or
let hostlist = Hostlist::new("node[1-3,5]")?;
for host in &hostlist {
println!("{host}");
}
Ok(())
}
output:
node1
node2
node3
node5
If you just want a Vec of host names, you can either collect() them from a
Hostlist, or use the expand_hostlist convenience function:
use hostlist_iter::expand_hostlist;
fn example() -> Result<(), hostlist_iter::Error> {
let hosts = expand_hostlist("node[1-3,5]")?;
assert_eq!(hosts, vec!["node1", "node2", "node3", "node5"]);
Ok(())
}
Note: Using expand_hostlist or collecting hosts into a Vec will not achieve
the memory footprint feature mentioned above.
Use the collapse_hosts function:
use hostlist_iter::collapse_hosts;
fn example() -> Result<(), hostlist_iter::Error> {
let hosts = vec!["n6", "n2", "n3", "n1", "abc1"];
let hostlist = collapse_hosts(hosts)?;
assert_eq!(hostlist, "abc1,n[1-3,6]");
Ok(())
}
This crate provides custom Error and Result types. The most common error
variant is likely to be ParseError which contains a Box'd
pest::error::Error<Rule> with more details. All errors implement the Display
trait for user-friendly output.
use hostlist_iter::Hostlist;
fn example() {
match "bad[hostlist".parse::<Hostlist>() {
Ok(hostlist) => println!("Valid hostlist: {}", hostlist),
Err(e) => println!("Error parsing hostlist: {}", e),
}
}
The following Hostlists use the same amount of memory due to the internal
representation not expanding the entire range up front:
let hostlist1: Hostlist = "node[1-10]".parse()?;
let hostlist2: Hostlist = "node[1-1000000000]".parse()?;
Iterating over each hostlist will generate values on demand rather than storing them all in memory.
Pest's website provides a convenient exploration tool for grammar rules. You can enter your own hostlist expressions and see how they will be parsed.
link to Pest Editor for our grammar
(click "Wide Mode" for a better experience)
Hostlist - Main type representing a parsed hostlist expressionError - Error type for all operations in this crateResult<T> - Specialized result type for this crateHostlist::new(expr: &str) -> Result<Hostlist> - Parse a hostlist expressionexpand_hostlist(expr: &str) -> Result<Vec<String>> - Convert a hostlist to a vector of host namescollapse_hosts(hosts: impl IntoIterator<Item = impl AsRef<str>>) -> Result<String> - Convert host names to a compact(-ish) hostlist expressioncollapse_hosts only collapses along a single numeric suffix"n[001-002]" == ["n1", "n2"])This project is licensed under either of
at your option.