Open wez opened 8 months ago
I've thrown together a couple of helper functions to make this a little more ergonomic in my application, sharing here in case it is helpful, and/or influences the query API here in this crate.
I'm sorting the results because that matters for determinism and matching in tests, but I can see how that may not always be 100% desirable.
let hostnames: Vec<String> =
query_facts_scalar(&mut a, "data($name) <- hostname($name)")?;
/// Query facts and return them in a stable order.
fn query_facts<T, R, E>(authorizer: &mut Authorizer, query: R) -> Result<Vec<T>, Token>
where
R: TryInto<Rule>,
T: TryFrom<Fact, Error = E> + Ord,
E: Into<Token>,
Token: From<<R as TryInto<Rule>>::Error>,
{
let mut data = authorizer.query(query)?;
data.sort();
Ok(data)
}
/// Query a set of scalar facts and return them in a stable order.
fn query_facts_scalar<T, R, E>(authorizer: &mut Authorizer, query: R) -> Result<Vec<T>, Token>
where
R: TryInto<Rule>,
E: Into<Token>,
Token: From<<R as TryInto<Rule>>::Error>,
(T,): TryFrom<Fact, Error = E> + Ord,
{
let mut data: Vec<(T,)> = query_facts(authorizer, query)?;
let data: Vec<T> = data.into_iter().map(|t| t.0).collect();
Ok(data)
}
I wanted to do this:
but:
I found that I can do this using tuple syntax and then converting, but it is somewhat verbose and since the order of the generics puts
T
as the second parameter, it becomes impossible to try to make this into a one-liner because all of the required generics are not easily named in a one liner:I also tried making a newtype wrapper around string to handle the conversion, but it does not solve the need for an additional remapping of the array into the underlying type.
I suppose this request generalizes to allowing non-tuple variants of the other types that work with the
(T,)
syntax.See also: