protobuf_codegen/customize/
mod.rspub(crate) mod ctx;
pub(crate) mod rustproto_proto;
use std::fmt;
use std::ops::Deref;
use std::rc::Rc;
use protobuf::reflect::EnumDescriptor;
use protobuf::reflect::FieldDescriptor;
use protobuf::reflect::FileDescriptor;
use protobuf::reflect::MessageDescriptor;
use protobuf::reflect::OneofDescriptor;
pub trait CustomizeCallback: 'static {
fn file(&self, file: &FileDescriptor) -> Customize {
let _ = file;
Customize::default()
}
fn message(&self, message: &MessageDescriptor) -> Customize {
let _ = message;
Customize::default()
}
fn field(&self, field: &FieldDescriptor) -> Customize {
let _ = field;
Customize::default()
}
fn special_field(&self, message: &MessageDescriptor, field: &str) -> Customize {
let _ = (message, field);
Customize::default()
}
fn enumeration(&self, enum_type: &EnumDescriptor) -> Customize {
let _ = enum_type;
Customize::default()
}
fn oneof(&self, oneof: &OneofDescriptor) -> Customize {
let _ = oneof;
Customize::default()
}
}
pub(crate) struct CustomizeCallbackDefault;
impl CustomizeCallback for CustomizeCallbackDefault {}
#[derive(Clone)]
pub(crate) struct CustomizeCallbackHolder(pub(crate) Rc<dyn CustomizeCallback>);
impl CustomizeCallbackHolder {
pub(crate) fn new(callback: impl CustomizeCallback) -> CustomizeCallbackHolder {
CustomizeCallbackHolder(Rc::new(callback))
}
}
impl Deref for CustomizeCallbackHolder {
type Target = dyn CustomizeCallback;
fn deref(&self) -> &Self::Target {
&*self.0
}
}
impl Default for CustomizeCallbackHolder {
fn default() -> Self {
CustomizeCallbackHolder(Rc::new(CustomizeCallbackDefault))
}
}
impl PartialEq for CustomizeCallbackHolder {
fn eq(&self, other: &Self) -> bool {
Rc::ptr_eq(&self.0, &other.0)
}
}
impl fmt::Debug for CustomizeCallbackHolder {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("CustomizeCallbackWrapper")
.finish_non_exhaustive()
}
}
#[derive(Default, Debug, Clone, PartialEq)]
pub struct Customize {
pub(crate) before: Option<String>,
pub(crate) generate_accessors: Option<bool>,
pub(crate) generate_getter: Option<bool>,
pub(crate) tokio_bytes: Option<bool>,
pub(crate) tokio_bytes_for_string: Option<bool>,
pub(crate) oneofs_non_exhaustive: Option<bool>,
pub(crate) lite_runtime: Option<bool>,
pub(crate) gen_mod_rs: Option<bool>,
pub(crate) inside_protobuf: Option<bool>,
pub(crate) btreemap: Option<bool>,
}
#[derive(Debug, thiserror::Error)]
pub(crate) enum CustomizeParseParameterError {
#[error("Cannot parse bool option value: {:?}", .0)]
CannotParseBool(String),
#[error("Unknown option name: {:?}", .0)]
UnknownOptionName(String),
}
impl Customize {
pub fn before(mut self, before: &str) -> Self {
self.before = Some(before.to_owned());
self
}
pub fn generate_accessors(mut self, generate_accessors: bool) -> Self {
self.generate_accessors = Some(generate_accessors);
self
}
pub fn generate_getter(mut self, generate_getter: bool) -> Self {
self.generate_getter = Some(generate_getter);
self
}
pub fn tokio_bytes(mut self, tokio_bytes: bool) -> Self {
self.tokio_bytes = Some(tokio_bytes);
self
}
pub fn tokio_bytes_for_string(mut self, tokio_bytes_for_string: bool) -> Self {
self.tokio_bytes_for_string = Some(tokio_bytes_for_string);
self
}
pub fn oneofs_non_exhaustive(mut self, non_exhaustive: bool) -> Self {
self.oneofs_non_exhaustive = Some(non_exhaustive);
self
}
pub fn lite_runtime(mut self, lite_runtime: bool) -> Self {
self.lite_runtime = Some(lite_runtime);
self
}
pub fn gen_mod_rs(mut self, gen_mod_rs: bool) -> Self {
self.gen_mod_rs = Some(gen_mod_rs);
self
}
pub fn inside_protobuf(mut self, inside_protobuf: bool) -> Self {
self.inside_protobuf = Some(inside_protobuf);
self
}
pub fn btreemaps(self, use_btreemaps: bool) -> Self {
Self {
btreemap: Some(use_btreemaps),
..self
}
}
pub fn update_with(&mut self, that: &Customize) {
if let Some(v) = &that.before {
self.before = Some(v.clone());
}
if let Some(v) = that.generate_accessors {
self.generate_accessors = Some(v);
}
if let Some(v) = that.generate_getter {
self.generate_getter = Some(v);
}
if let Some(v) = that.tokio_bytes {
self.tokio_bytes = Some(v);
}
if let Some(v) = that.tokio_bytes_for_string {
self.tokio_bytes_for_string = Some(v);
}
if let Some(v) = that.lite_runtime {
self.lite_runtime = Some(v);
}
if let Some(v) = that.gen_mod_rs {
self.gen_mod_rs = Some(v);
}
if let Some(v) = that.inside_protobuf {
self.inside_protobuf = Some(v);
}
if let Some(v) = that.btreemap {
self.btreemap = Some(v);
}
}
pub fn set_defaults_from(&mut self, other: &Customize) {
let mut tmp = other.clone();
tmp.update_with(self);
*self = tmp;
}
pub fn parse_from_parameter(parameter: &str) -> anyhow::Result<Customize> {
fn parse_bool(v: &str) -> anyhow::Result<bool> {
v.parse()
.map_err(|_| CustomizeParseParameterError::CannotParseBool(v.to_owned()).into())
}
let mut r = Customize::default();
for nv in parameter.split_whitespace() {
let (n, v) = match nv.find('=') {
Some(eq) => {
let n = &nv[..eq];
let v = &nv[eq + 1..];
(n, v)
}
None => (nv, "true"),
};
if n == "generate_accessors" {
r.generate_accessors = Some(parse_bool(v)?);
} else if n == "generate_getter" {
r.generate_getter = Some(parse_bool(v)?);
} else if n == "tokio_bytes" {
r.tokio_bytes = Some(parse_bool(v)?);
} else if n == "tokio_bytes_for_string" {
r.tokio_bytes_for_string = Some(parse_bool(v)?);
} else if n == "lite_runtime" {
r.lite_runtime = Some(parse_bool(v)?);
} else if n == "gen_mod_rs" {
r.gen_mod_rs = Some(parse_bool(v)?);
} else if n == "btreemap" {
r.btreemap = Some(parse_bool(v)?);
} else if n == "inside_protobuf" {
r.inside_protobuf = Some(parse_bool(v)?);
} else if n == "lite" {
r.lite_runtime = Some(parse_bool(v)?);
} else {
return Err(CustomizeParseParameterError::UnknownOptionName(n.to_owned()).into());
}
}
Ok(r)
}
}