#![doc(html_root_url = "https://docs.rs/minifix/")]
#![warn(missing_docs)]
#![deny(
//unused FIXME,
missing_debug_implementations,
unsafe_op_in_unsafe_fn,
rustdoc::broken_intra_doc_links,
//missing_docs FIXME,
unconditional_recursion,
unstable_name_collisions,
clippy::useless_conversion,
clippy::missing_panics_doc,
clippy::mixed_case_hex_literals,
clippy::needless_bool,
clippy::needless_lifetimes,
rustdoc::invalid_rust_codeblocks
)]
#![cfg_attr(doc_cfg, feature(doc_cfg))]
mod buffer;
mod field_access;
pub mod utils;
pub mod definitions;
pub mod field_types;
pub mod prelude;
pub mod session;
pub use field_access::{FieldMap, GroupEntries, RepeatingGroup};
pub mod tagvalue;
#[cfg(feature = "json-encoding")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "json-encoding")))]
pub mod json;
#[cfg(feature = "utils-tokio")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "utils-tokio")))]
pub mod tokio;
pub use buffer::{Buffer, BufferWriter};
#[cfg(feature = "codegen")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "codegen")))]
pub use minifix_codegen as codegen;
#[doc(hidden)]
pub use minifix_derive::FieldType;
pub use minifix_dictionary::{self as dict, Dictionary, TagU32};
pub trait GetConfig {
type Config;
fn config(&self) -> &Self::Config;
fn config_mut(&mut self) -> &mut Self::Config;
}
pub trait FieldType<'a>
where
Self: Sized,
{
type Error;
type SerializeSettings: Default;
fn serialize<B>(&self, buffer: &mut B) -> usize
where
B: Buffer,
{
self.serialize_with(buffer, Self::SerializeSettings::default())
}
fn serialize_with<B>(
&self,
buffer: &mut B,
settings: Self::SerializeSettings,
) -> usize
where
B: Buffer;
fn deserialize(data: &'a [u8]) -> Result<Self, Self::Error>;
fn deserialize_lossy(data: &'a [u8]) -> Result<Self, Self::Error> {
Self::deserialize(data)
}
fn to_bytes(&self) -> Vec<u8> {
let mut buffer = Vec::new();
self.serialize(&mut buffer);
buffer
}
fn to_string(&self) -> String {
String::from_utf8(self.to_bytes())
.expect("Invalid UTF-8 representation of FIX field.")
}
}
pub trait StreamingDecoder {
type Buffer: Buffer;
type Error;
fn buffer(&mut self) -> &mut Self::Buffer;
fn clear(&mut self) {
self.buffer().clear();
}
fn num_bytes_required(&self) -> usize;
fn fillable(&mut self) -> &mut [u8] {
let len = self.buffer().len();
let num_bytes_required = self.num_bytes_required();
self.buffer().resize(num_bytes_required, 0);
&mut self.buffer().as_mut_slice()[len..]
}
fn try_parse(&mut self) -> Result<Option<()>, Self::Error>;
}
pub trait SetField<F> {
fn set<'a, V>(&'a mut self, field: F, value: V)
where
V: FieldType<'a>,
{
self.set_with(
field,
value,
<V::SerializeSettings as Default>::default(),
)
}
fn set_with<'a, V>(
&'a mut self,
field: F,
value: V,
setting: V::SerializeSettings,
) where
V: FieldType<'a>;
}
#[derive(Debug, thiserror::Error)]
pub enum FieldValueError<E> {
#[error("Missing field tag")]
Missing,
#[error("Invalid field value: {0}")]
Invalid(#[from] E),
}
impl<E> PartialEq<FieldValueError<E>> for FieldValueError<E> {
fn eq(&self, other: &FieldValueError<E>) -> bool {
match (self, other) {
(FieldValueError::Missing, FieldValueError::Missing) => true,
_ => false,
}
}
}
impl<E> From<Option<E>> for FieldValueError<E> {
fn from(e: Option<E>) -> Self {
match e {
Some(e) => FieldValueError::Invalid(e),
None => FieldValueError::Missing,
}
}
}