I'm very happy with Varlink so far as a means to create a CLI "server" and "client". It's basically RPC with a nice standard and autogenerated code.
The trouble is that based on the autogen code, Varlink methods expect owned variables as args. As a result, I'm writing code that duplicates work for the sake of ownership (note that keys1
and keys2
are the exact same thing):
pub fn run_client(addr: &str, tally: Arc<RwLock<Tally>>) -> Result<()> {
let conn = Connection::with_address(&addr).unwrap();
let mut iface = org_wordtree_ngrams::VarlinkClient::new(conn);
let mut score: f64 = 0.0;
let tally = tally.read().unwrap();
let keys1: Vec<String> =
tally.iter().map(|(k, _v)| k.clone() ).collect();
let keys2: Vec<String> =
tally.iter().map(|(k, _v)| k.clone() ).collect();
let reply = iface.lookup_all(keys1).call()?;
for (key, baseline) in keys2.iter().zip(reply.tallies.iter()) {
let baseline = *baseline as f64;
if baseline > 0.0 {
let value = match tally.get(key) {
Some(v) => *v,
None => 0
};
score += (value as f64) / (baseline as f64)
}
}
println!("Score: {:.*}", 9, score);
Ok(())
}
(Full source code can be found here.)
The autogenerated lookup_all
method signature looks like this, which is what's making me dance around borrowing:
fn lookup_all(&self, call: &mut Call_LookupAll, r#ngrams: Vec<String>) -> varlink::Result<()>;
I'm quite new to Rust, so I'm sure there's a better way. I'm primarily interested in speed. Any suggestions?