#[cfg(any(feature = "auth", feature = "profile"))] enum Entity { #[cfg(feature = "auth")] Auth, #[cfg(feature = "profile")] Profile, } #[cfg(any(feature = "auth", feature = "profile"))] impl Entity { fn protos(&self) -> Vec<&'static str> { let mut res: Vec<&'static str> = vec![]; match self { #[cfg(feature = "auth")] Entity::Auth => { res.extend(vec!["proto/auth/auth.proto"]); }, #[cfg(feature = "profile")] Entity::Profile => { res.extend(vec!["proto/profile/profile.proto"]); } } res } } fn main() -> Result<(), Box> { println!("cargo:rerun-if-changed=proto"); #[cfg(feature = "auth")] build_proto("auth", Entity::Auth); #[cfg(feature = "profile")] build_proto("profile", Entity::Profile); Ok(()) } #[cfg(any(feature = "auth", feature = "profile"))] fn build_proto(package: &str, entity: Entity) { let out_dir = std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap()); let config = tonic_build::configure().compile_well_known_types(true) .server_mod_attribute( package, format!("#[cfg(feature = \"{package}\")] #[cfg_attr(docsrs, doc(cfg(feature = \"{package}\")))]"), ) .client_mod_attribute( package, format!("#[cfg(feature = \"{package}\")] #[cfg_attr(docsrs, doc(cfg(feature = \"{package}\")))]"), ); #[cfg(feature = "serde")] let config = add_serde(config); #[cfg(feature = "time")] let config = config .type_attribute( ".google.protobuf.Timestamp", "#[serde(try_from = \"crate::google::helpers::DateItem\")] #[serde(into = \"String\")]", ) .type_attribute( ".google.type.Date", "#[serde(try_from = \"crate::google::helpers::DateItem\")] #[serde(into = \"String\")]", ); let include_paths = &["proto"]; config .file_descriptor_set_path(out_dir.join(format!("{package}_descriptor.bin"))) .server_mod_attribute( package, format!("#[cfg(feature = \"{package}\")] #[cfg_attr(docsrs, doc(cfg(feature = \"{package}\")))]"), ) .client_mod_attribute( package, format!("#[cfg(feature = \"{package}\")] #[cfg_attr(docsrs, doc(cfg(feature = \"{package}\")))]"), ) .compile_well_known_types(true) .compile_protos(&entity.protos(), include_paths).unwrap(); } #[cfg(all(feature = "serde", any(feature = "auth",feature = "profile")))] fn add_serde(config: tonic_build::Builder) -> tonic_build::Builder { config.type_attribute( ".", "#[derive(serde::Serialize, serde::Deserialize)] #[serde(rename_all = \"snake_case\")]", ) }