tvl-depot/users/Profpatsch/cdb.nix
Vincent Ambo aa122cbae7 style: format entire depot with nixpkgs-fmt
This CL can be used to compare the style of nixpkgs-fmt against other
formatters (nixpkgs, alejandra).

Change-Id: I87c6abff6bcb546b02ead15ad0405f81e01b6d9e
Reviewed-on: https://cl.tvl.fyi/c/depot/+/4397
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
Reviewed-by: lukegb <lukegb@tvl.fyi>
Reviewed-by: wpcarro <wpcarro@gmail.com>
Reviewed-by: Profpatsch <mail@profpatsch.de>
Reviewed-by: kanepyork <rikingcoding@gmail.com>
Reviewed-by: tazjin <tazjin@tvl.su>
Reviewed-by: cynthia <cynthia@tvl.fyi>
Reviewed-by: edef <edef@edef.eu>
Reviewed-by: eta <tvl@eta.st>
Reviewed-by: grfn <grfn@gws.fyi>
2022-01-31 16:11:53 +00:00

93 lines
3.5 KiB
Nix
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{ depot, pkgs, ... }:
let
cdbListToNetencode = depot.nix.writers.rustSimple
{
name = "cdb-list-to-netencode";
dependencies = [
depot.third_party.rust-crates.nom
depot.users.Profpatsch.execline.exec-helpers
depot.users.Profpatsch.netencode.netencode-rs
];
} ''
extern crate nom;
extern crate exec_helpers;
extern crate netencode;
use std::collections::HashMap;
use std::io::BufRead;
use nom::{IResult};
use nom::sequence::{tuple};
use nom::bytes::complete::{tag, take};
use nom::character::complete::{digit1, char};
use nom::error::{context, ErrorKind, ParseError};
use nom::combinator::{map_res};
use netencode::{T, Tag};
fn usize_t(s: &[u8]) -> IResult<&[u8], usize> {
context(
"usize",
map_res(
map_res(digit1, |n| std::str::from_utf8(n)),
|s| s.parse::<usize>())
)(s)
}
fn parse_cdb_record(s: &[u8]) -> IResult<&[u8], (&[u8], &[u8])> {
let (s, (_, klen, _, vlen, _)) = tuple((
char('+'),
usize_t,
char(','),
usize_t,
char(':')
))(s)?;
let (s, (key, _, val)) = tuple((
take(klen),
tag("->"),
take(vlen),
))(s)?;
Ok((s, (key, val)))
}
fn main() {
let mut res = vec![];
let stdin = std::io::stdin();
let mut lines = stdin.lock().split(b'\n');
loop {
match lines.next() {
None => exec_helpers::die_user_error("cdb-list-to-netencode", "stdin ended but we didnt receive the empty line to signify the end of the cdbdump input!"),
Some(Err(err)) => exec_helpers::die_temporary("cdb-list-to-netencode", format!("could not read from stdin: {}", err)),
Some(Ok(line)) =>
if &line == b"" {
// the cdbdump input ends after an empty line (double \n)
break;
} else {
match parse_cdb_record(&line) {
Ok((b"", (key, val))) => {
let (key, val) = match
std::str::from_utf8(key)
.and_then(|k| std::str::from_utf8(val).map(|v| (k, v))) {
Ok((key, val)) => (key.to_owned(), val.to_owned()),
Err(err) => exec_helpers::die_user_error("cdb-list-to-netencode", format!("cannot decode line {:?}, we only support utf8-encoded key/values pairs for now: {}", String::from_utf8_lossy(&line), err)),
};
let _ = res.push((key, val));
},
Ok((rest, _)) => exec_helpers::die_user_error("cdb-list-to-netencode", format!("could not decode record line {:?}, had some trailing bytes", String::from_utf8_lossy(&line))),
Err(err) => exec_helpers::die_user_error("cdb-list-to-netencode", format!("could not decode record line {:?}: {:?}", String::from_utf8_lossy(&line), err)),
}
}
}
}
let list = T::List(res.into_iter().map(
|(k, v)| T::Record(vec![(String::from("key"), T::Text(k)), (String::from("val"), T::Text(v))].into_iter().collect())
).collect());
netencode::encode(&mut std::io::stdout(), &list.to_u());
}
'';
in
{
inherit
cdbListToNetencode
;
}