///|
/// Serialize a parsed Range field without sorting or coalescing specs.
pub fn serialize_range(request : RangeRequest) -> String {
match request.unit() {
Bytes => {
let parts : Array[String] = []
for spec in request.specs() {
parts.push(serialize_byte_spec(spec))
}
"bytes=\{join_strings(parts, ",")}"
}
Other(unit) => "\{unit}=\{request.raw_other_range_set().unwrap_or("")}"
}
}
///|
/// Parse then serialize; syntax normalization does not merge ranges.
pub fn canonicalize_range(input : String) -> Result[String, RangeError] {
match parse_range(input) {
Ok(request) => Ok(serialize_range(request))
Err(error) => Err(error)
}
}
///|
fn serialize_byte_spec(spec : ByteRangeSpec) -> String {
match spec {
Closed(first, last) => "\{first}-\{last}"
OpenEnded(first) => "\{first}-"
Suffix(length) => "-\{length}"
}
}
///|
fn join_strings(values : Array[String], separator : String) -> String {
let builder = StringBuilder()
for i = 0; i < values.length(); i = i + 1 {
if i > 0 {
builder.write_string(separator)
}
builder.write_string(values[i])
}
builder.to_string()
}