blob: bbd3298a6d908d03cd4c3282b25326c6111a7dba [file] [log] [blame]
use std::prelude::v1::*;
use std::any::Any;
#[cfg(feature = "bytes")]
use bytes::Bytes;
#[cfg(feature = "bytes")]
use chars::Chars;
use protocore::*;
use super::*;
pub trait ProtobufValue: Any + 'static {
fn as_ref(&self) -> ProtobufValueRef;
fn as_any(&self) -> &Any {
unimplemented!()
}
fn is_non_zero(&self) -> bool {
self.as_ref().is_non_zero()
}
fn as_ref_copy(&self) -> ProtobufValueRef<'static>
//where Self : Copy // TODO
{
match self.as_ref() {
ProtobufValueRef::Bool(v) => ProtobufValueRef::Bool(v),
ProtobufValueRef::U32(v) => ProtobufValueRef::U32(v),
ProtobufValueRef::U64(v) => ProtobufValueRef::U64(v),
ProtobufValueRef::I32(v) => ProtobufValueRef::I32(v),
ProtobufValueRef::I64(v) => ProtobufValueRef::I64(v),
ProtobufValueRef::F32(v) => ProtobufValueRef::F32(v),
ProtobufValueRef::F64(v) => ProtobufValueRef::F64(v),
ProtobufValueRef::Enum(v) => ProtobufValueRef::Enum(v),
ProtobufValueRef::String(..) |
ProtobufValueRef::Bytes(..) |
ProtobufValueRef::Message(..) => unreachable!(),
}
}
}
impl ProtobufValue for u32 {
fn as_ref(&self) -> ProtobufValueRef {
ProtobufValueRef::U32(*self)
}
}
impl ProtobufValue for u64 {
fn as_ref(&self) -> ProtobufValueRef {
ProtobufValueRef::U64(*self)
}
}
impl ProtobufValue for i32 {
fn as_ref(&self) -> ProtobufValueRef {
ProtobufValueRef::I32(*self)
}
}
impl ProtobufValue for i64 {
fn as_ref(&self) -> ProtobufValueRef {
ProtobufValueRef::I64(*self)
}
}
impl ProtobufValue for f32 {
fn as_ref(&self) -> ProtobufValueRef {
ProtobufValueRef::F32(*self)
}
}
impl ProtobufValue for f64 {
fn as_ref(&self) -> ProtobufValueRef {
ProtobufValueRef::F64(*self)
}
}
impl ProtobufValue for bool {
fn as_ref(&self) -> ProtobufValueRef {
ProtobufValueRef::Bool(*self)
}
}
impl ProtobufValue for String {
fn as_ref(&self) -> ProtobufValueRef {
ProtobufValueRef::String(*&self)
}
}
impl ProtobufValue for str {
fn as_ref(&self) -> ProtobufValueRef {
ProtobufValueRef::String(self)
}
}
impl ProtobufValue for Vec<u8> {
fn as_ref(&self) -> ProtobufValueRef {
ProtobufValueRef::Bytes(*&self)
}
}
#[cfg(feature = "bytes")]
impl ProtobufValue for Bytes {
fn as_ref(&self) -> ProtobufValueRef {
ProtobufValueRef::Bytes(&*self)
}
}
#[cfg(feature = "bytes")]
impl ProtobufValue for Chars {
fn as_ref(&self) -> ProtobufValueRef {
ProtobufValueRef::String(&*self)
}
}
// conflicting implementations, so generated code is used instead
/*
impl<E : ProtobufEnum> ProtobufValue for E {
fn as_ref(&self) -> ProtobufValueRef {
ProtobufValueRef::Enum(self.descriptor())
}
}
impl<M : Message> ProtobufValue for M {
fn as_ref(&self) -> ProtobufValueRef {
ProtobufValueRef::Message(self)
}
}
*/
pub enum ProtobufValueRef<'a> {
U32(u32),
U64(u64),
I32(i32),
I64(i64),
F32(f32),
F64(f64),
Bool(bool),
String(&'a str),
Bytes(&'a [u8]),
Enum(&'static EnumValueDescriptor),
Message(&'a Message),
}
impl<'a> ProtobufValueRef<'a> {
pub fn is_non_zero(&self) -> bool {
match *self {
ProtobufValueRef::U32(v) => v != 0,
ProtobufValueRef::U64(v) => v != 0,
ProtobufValueRef::I32(v) => v != 0,
ProtobufValueRef::I64(v) => v != 0,
ProtobufValueRef::F32(v) => v != 0.,
ProtobufValueRef::F64(v) => v != 0.,
ProtobufValueRef::Bool(v) => v,
ProtobufValueRef::String(v) => !v.is_empty(),
ProtobufValueRef::Bytes(v) => !v.is_empty(),
ProtobufValueRef::Enum(v) => v.value() != 0,
ProtobufValueRef::Message(_) => true,
}
}
}