#[test]
fn default_features_core_types_accessible() {
fn _check_oxi_message_trait_bound<T: oxiproto::OxiMessage>() {}
fn _check_oxi_name_trait_bound<T: oxiproto::OxiName>() {}
fn _check_oxi_oneof_trait_bound<T: oxiproto::OxiOneof>() {}
fn _check_extensions_struct_accessible(_: oxiproto::Extensions) {}
let _ = _check_extensions_struct_accessible;
let v = oxiproto::version();
assert!(!v.is_empty(), "version() must always be available");
}
#[test]
fn wire_module_always_available() {
let _: oxiproto::wire::WireType = oxiproto::wire::WireType::Varint;
let buf = oxiproto::wire::EncodeBuffer::new();
drop(buf);
let _: oxiproto::wire::UnknownFields = Default::default();
}
#[test]
fn prelude_always_available() {
use oxiproto::prelude::*;
fn _check_wire_type(_: WireType) {}
fn _check_encode_buffer(_: EncodeBuffer) {}
fn _check_oxi_error(_: OxiProtoError) {}
fn _check_oxi_result(_: OxiProtoResult<()>) {}
let _ = _check_wire_type;
let _ = _check_encode_buffer;
let _ = _check_oxi_error;
let _ = _check_oxi_result;
}
#[test]
fn encode_decode_helpers_always_available() {
use oxiproto::{OxiMessage, OxiName, OxiProtoError, OxiProtoResult};
#[derive(Debug, Default, Clone, PartialEq)]
struct Ping {
value: i32,
}
impl OxiName for Ping {
const NAME: &'static str = "Ping";
const PACKAGE: &'static str = "test";
}
impl OxiMessage for Ping {
fn encoded_len(&self) -> usize {
if self.value != 0 {
1 + oxiproto::wire::varint::encoded_len_varint(self.value as u64)
} else {
0
}
}
fn encode_raw(&self, buf: &mut oxiproto::wire::EncodeBuffer) {
if self.value != 0 {
buf.write_tag(1, oxiproto::wire::WireType::Varint)
.expect("write_tag");
buf.write_varint(self.value as u64);
}
}
fn merge(&mut self, buf: &mut oxiproto::wire::DecodeBuffer) -> OxiProtoResult<()> {
while !buf.is_empty() {
let tag = match buf.read_tag() {
Ok(t) => t,
Err(oxiproto::wire::WireError::UnexpectedEof) => break,
Err(e) => return Err(OxiProtoError::WireFormatError(e)),
};
match (tag.field_number, tag.wire_type) {
(1, oxiproto::wire::WireType::Varint) => {
self.value =
buf.read_varint().map_err(OxiProtoError::WireFormatError)? as i32;
}
(_, wt) => {
buf.skip_field(wt).map_err(OxiProtoError::WireFormatError)?;
}
}
}
Ok(())
}
fn clear(&mut self) {
self.value = 0;
}
}
let msg = Ping { value: 7 };
let bytes = oxiproto::encode(&msg);
assert!(
!bytes.is_empty(),
"encode must produce non-empty bytes for non-default value"
);
let back: Ping = oxiproto::decode(&bytes).expect("decode must succeed");
assert_eq!(back, msg, "encode/decode round-trip must preserve value");
let empty = Ping::default();
let empty_bytes = oxiproto::encode(&empty);
assert!(
empty_bytes.is_empty(),
"default value must encode to zero bytes (proto3)"
);
}
#[cfg(feature = "build")]
#[test]
fn build_feature_exposes_build_module() {
let type_name = std::any::type_name::<oxiproto::build::Builder>();
assert!(
type_name.contains("Builder"),
"oxiproto::build::Builder must be accessible: {type_name}"
);
}
#[cfg(feature = "build")]
#[test]
fn build_feature_exposes_builder_type() {
let builder = oxiproto::build::Builder::new();
drop(builder);
}
#[cfg(feature = "build")]
#[test]
fn build_feature_exposes_compile_to_fds() {
let result =
oxiproto::build::compile_to_fds(&[] as &[&std::path::Path], &[] as &[&std::path::Path]);
let _ = result;
}
#[cfg(feature = "reflect")]
#[test]
fn reflect_feature_exposes_reflect_module() {
fn _accepts_pool(_: &oxiproto::reflect::DescriptorPool) {}
let _ = _accepts_pool;
}
#[cfg(feature = "wkt")]
#[test]
fn wkt_feature_exposes_wkt_module() {
fn _uses_timestamp_ext<T: oxiproto::wkt::TimestampExt>(_: &T) {}
let _ = _uses_timestamp_ext::<oxiproto::prost_types::Timestamp>;
}
#[cfg(feature = "wkt")]
#[test]
fn wkt_duration_ext_accessible() {
fn _uses_duration_ext<T: oxiproto::wkt::DurationExt>(_: &T) {}
let _ = _uses_duration_ext::<oxiproto::prost_types::Duration>;
}
#[cfg(feature = "codegen")]
#[test]
fn codegen_feature_exposes_codegen_module() {
let opts = oxiproto::codegen::CodegenOptions::new();
assert!(!opts.emit_json, "emit_json default must be false");
assert!(
!opts.emit_oxi_message_impl,
"emit_oxi_message_impl default must be false"
);
}
#[cfg(feature = "codegen")]
#[test]
fn codegen_generate_with_options_accessible() {
use prost_types::{FileDescriptorProto, FileDescriptorSet};
let fds = FileDescriptorSet {
file: vec![FileDescriptorProto {
name: Some("empty.proto".to_string()),
..Default::default()
}],
};
let opts = oxiproto::codegen::CodegenOptions::new();
let result = oxiproto::codegen::generate_with_options(&fds, &opts);
assert!(
result.is_ok(),
"generate_with_options on empty FDS must not fail"
);
}
#[cfg(feature = "json")]
#[test]
fn json_feature_exposes_json_module() {
fn _accepts_codec(_: &oxiproto::json::JsonCodec) {}
let _ = _accepts_codec;
}
#[cfg(not(feature = "build"))]
#[test]
fn build_module_absent_without_feature_documented() {
let _ = true;
}
#[cfg(not(feature = "reflect"))]
#[test]
fn reflect_module_absent_without_feature_documented() {
let _ = true;
}
#[cfg(not(feature = "wkt"))]
#[test]
fn wkt_module_absent_without_feature_documented() {
let _ = true;
}
#[cfg(not(feature = "codegen"))]
#[test]
fn codegen_module_absent_without_feature_documented() {
let _ = true;
}
#[cfg(not(feature = "json"))]
#[test]
fn json_module_absent_without_feature_documented() {
let _ = true;
}