autocxx_parser/
multi_bindings.rsuse indexmap::IndexMap;
use proc_macro2::TokenStream;
use serde::{Deserialize, Serialize};
use crate::IncludeCppConfig;
#[derive(Serialize, Deserialize, Default)]
pub struct MultiBindings(IndexMap<u64, String>);
use thiserror::Error;
#[derive(Error, Debug)]
pub enum MultiBindingsErr {
#[error("unable to find the desired bindings within the archive of Rust bindings produced by the autocxx code generation phase")]
MissingBindings,
#[error("the stored bindings within the JSON file could not be parsed as valid Rust tokens")]
BindingsNotParseable,
}
impl MultiBindings {
pub fn insert(&mut self, config: &IncludeCppConfig, bindings: TokenStream) {
self.0.insert(config.get_hash(), bindings.to_string());
}
pub fn get(&self, config: &IncludeCppConfig) -> Result<TokenStream, MultiBindingsErr> {
match self.0.get(&(config.get_hash())) {
None => Err(MultiBindingsErr::MissingBindings),
Some(bindings) => Ok(bindings
.parse()
.map_err(|_| MultiBindingsErr::BindingsNotParseable)?),
}
}
}
#[cfg(test)]
mod tests {
use proc_macro2::Span;
use quote::quote;
use syn::parse_quote;
use crate::IncludeCppConfig;
use super::MultiBindings;
#[test]
fn test_multi_bindings() {
let hexathorpe = syn::token::Pound(Span::call_site());
let config1: IncludeCppConfig = parse_quote! {
#hexathorpe include "a.h"
generate!("Foo")
};
let config2: IncludeCppConfig = parse_quote! {
#hexathorpe include "b.h"
generate!("Bar")
};
let config3: IncludeCppConfig = parse_quote! {
#hexathorpe include "c.h"
generate!("Bar")
};
let mut multi_bindings = MultiBindings::default();
multi_bindings.insert(&config1, quote! { first; });
multi_bindings.insert(&config2, quote! { second; });
let json = serde_json::to_string(&multi_bindings).unwrap();
let multi_bindings2: MultiBindings = serde_json::from_str(&json).unwrap();
assert_eq!(
multi_bindings2.get(&config2).unwrap().to_string(),
"second ;"
);
assert_eq!(
multi_bindings2.get(&config1).unwrap().to_string(),
"first ;"
);
assert!(multi_bindings2.get(&config3).is_err());
}
}