use std::io;
use std::marker::PhantomData;
use crate::{
ensure_wire_format,
varint,
wire_format,
Message,
PbBufferReader,
Unrecognized,
};
pub trait Extensible: Message {
fn get_extension<E: Extension<Extendee = Self>>(&self, extension: E) -> E::Value {
extension.get_or_default(self)
}
fn get_extension_opt<E: Extension<Extendee = Self>>(&self, extension: E) -> io::Result<E::MaybeValue> {
extension.get(self)
}
#[doc(hidden)]
fn _extensions(&self) -> &Unrecognized;
}
pub trait Extension {
type Extendee: Extensible;
type MaybeValue;
type Value;
fn get(&self, m: &Self::Extendee) -> io::Result<Self::MaybeValue>;
fn get_or_default(&self, m: &Self::Extendee) -> Self::Value;
}
pub struct SingularExtension<T, U> {
pub field_number: u32,
pub wire_format: wire_format::Type,
pub name: &'static str,
pub default: fn() -> U,
_phantom: PhantomData<fn(&T) -> U>,
}
impl<T, U> SingularExtension<T, U> {
pub const fn new(
field_number: u32,
wire_format: wire_format::Type,
name: &'static str,
default: fn() -> U,
) -> Self {
Self {
field_number,
wire_format,
name,
default,
_phantom: PhantomData,
}
}
}
impl<T, U> Copy for SingularExtension<T, U> {}
impl<T, U> Clone for SingularExtension<T, U> {
fn clone(&self) -> Self {
*self
}
}
impl<T: Extensible, U: Message> Extension for SingularExtension<T, U> {
type Extendee = T;
type MaybeValue = Option<U>;
type Value = U;
fn get(&self, m: &Self::Extendee) -> io::Result<Option<U>> {
Ok(match m._extensions().get_singular_field(self.field_number) {
Some((field, wire_format)) => {
let mut buf = io::Cursor::new(field);
ensure_wire_format(wire_format, self.wire_format, self.name, self.field_number)?;
if wire_format == wire_format::Type::LengthDelimited {
varint::read(&mut buf)?;
}
let mut msg = U::default();
msg.deserialize(&mut buf)?;
Some(msg)
},
None => None,
})
}
fn get_or_default(&self, m: &Self::Extendee) -> Self::Value {
self.get(m).ok().flatten().unwrap_or_else(self.default)
}
}
pub struct RepeatedExtension<T, U> {
pub field_number: u32,
pub wire_format: wire_format::Type,
pub name: &'static str,
_phantom: PhantomData<fn(&T) -> U>,
}
impl<T, U> RepeatedExtension<T, U> {
pub const fn new(field_number: u32, wire_format: wire_format::Type, name: &'static str) -> Self {
Self {
field_number,
wire_format,
name,
_phantom: PhantomData,
}
}
}
impl<T, U> Copy for RepeatedExtension<T, U> {}
impl<T, U> Clone for RepeatedExtension<T, U> {
fn clone(&self) -> Self {
*self
}
}
impl<T: Extensible, U: Message> Extension for RepeatedExtension<T, U> {
type Extendee = T;
type MaybeValue = Vec<U>;
type Value = Vec<U>;
fn get(&self, m: &Self::Extendee) -> io::Result<Vec<U>> {
let mut result = vec![];
let mut buf = io::Cursor::new(m._extensions().get_fields(self.field_number));
while let Some((_field_number, wire_format)) = wire_format::read(&mut buf)? {
ensure_wire_format(wire_format, self.wire_format, self.name, self.field_number)?;
let mut msg = U::default();
if wire_format == wire_format::Type::LengthDelimited {
let length = varint::read(&mut buf)?.expect("corrupted Unrecognized");
msg.deserialize(&mut PbBufferReader::split(&mut buf, length as usize))?;
} else {
msg.deserialize(&mut buf)?;
}
result.push(msg);
}
Ok(result)
}
fn get_or_default(&self, m: &Self::Extendee) -> Self::Value {
self.get(m).unwrap_or_default()
}
}