extern crate core;
pub mod errors;
mod externs;
pub mod handlers;
mod hex;
pub mod log;
pub mod memory;
pub mod pb;
pub mod proto;
pub mod scalar;
mod state;
pub mod key;
pub mod store;
pub mod expr_parser;
pub use expr_parser::{expr_matcher, matches_keys_in_parsed_expr, ExprMatcher};
pub mod sqe;
mod operation;
pub mod testing;
pub mod prelude {
pub use crate::scalar::{BigDecimal, BigInt};
pub use crate::store::{
Appender, Delta, DeltaArray, DeltaBigDecimal, DeltaBigInt, DeltaBool, DeltaBytes,
DeltaFloat64, DeltaInt32, DeltaInt64, DeltaProto, DeltaString, Deltas, FoundationalStore,
StoreAdd, StoreAddBigDecimal, StoreAddBigInt, StoreAddFloat64, StoreAddInt64, StoreAppend,
StoreDelete, StoreGet, StoreGetBigDecimal, StoreGetBigInt, StoreGetFloat64, StoreGetInt64,
StoreGetProto, StoreGetRaw, StoreGetString, StoreMax, StoreMaxBigDecimal, StoreMaxBigInt,
StoreMaxFloat64, StoreMaxInt64, StoreMin, StoreMinBigDecimal, StoreMinBigInt,
StoreMinFloat64, StoreMinInt64, StoreNew, StoreSet, StoreSetBigDecimal, StoreSetBigInt,
StoreSetFloat64, StoreSetIfNotExists, StoreSetIfNotExistsBigDecimal,
StoreSetIfNotExistsBigInt, StoreSetIfNotExistsFloat64, StoreSetIfNotExistsInt64,
StoreSetIfNotExistsProto, StoreSetIfNotExistsRaw, StoreSetIfNotExistsString, StoreSetInt64,
StoreSetProto, StoreSetRaw, StoreSetString,
};
}
pub use crate::hex::Hex;
pub use hex_literal::hex;
#[cfg_attr(not(target_arch = "wasm32"), allow(unused_variables))]
pub fn output<M: ::buffa::Message>(msg: M) {
#[cfg(target_arch = "wasm32")]
{
let (ptr, len, buffer) = proto::encode_to_ptr(&msg);
std::mem::forget(buffer);
unsafe { externs::output(ptr, len as u32) }
}
}
#[cfg_attr(not(target_arch = "wasm32"), allow(unused_variables))]
pub fn skip_empty_output() {
#[cfg(target_arch = "wasm32")]
unsafe {
externs::skip_empty_output()
}
}
#[cfg_attr(not(target_arch = "wasm32"), allow(unused_variables))]
pub fn output_raw(data: Vec<u8>) {
#[cfg(target_arch = "wasm32")]
unsafe {
externs::output(data.as_ptr(), data.len() as u32)
}
}
pub use buffa;
pub use buffa_types;
pub mod lazy {
pub trait LazyDecode<'a>: Sized {
fn decode_lazy_slice(bytes: &'a [u8]) -> Result<Self, ::buffa::DecodeError>;
}
impl<'a, V> LazyDecode<'a> for V
where
V: ::buffa::view::LazyMessageView<'a>,
{
#[inline]
fn decode_lazy_slice(bytes: &'a [u8]) -> Result<Self, ::buffa::DecodeError> {
<V as ::buffa::view::LazyMessageView<'a>>::decode_lazy(bytes)
}
}
}
#[cfg(test)]
mod buffa_tests {
use crate::lazy::LazyDecode;
#[derive(Clone, Default, PartialEq)]
struct Block;
impl buffa::DefaultInstance for Block {
fn default_instance() -> &'static Self {
static DEFAULT: Block = Block;
&DEFAULT
}
}
impl buffa::Message for Block {
fn compute_size(&self, _cache: &mut buffa::SizeCache) -> u32 {
0
}
fn write_to(&self, _cache: &mut buffa::SizeCache, _buf: &mut impl buffa::EncodeSink) {}
fn merge_field(
&mut self,
tag: buffa::encoding::Tag,
buf: &mut impl bytes::Buf,
_ctx: buffa::DecodeContext<'_>,
) -> Result<(), buffa::DecodeError> {
buffa::encoding::skip_field(tag, buf)
}
fn clear(&mut self) {
*self = Self;
}
}
struct BlockLazyView<'a> {
buf: &'a [u8],
}
impl<'a> buffa::view::LazyMessageView<'a> for BlockLazyView<'a> {
type Owned = Block;
fn decode_lazy(buf: &'a [u8]) -> Result<Self, buffa::DecodeError> {
if buf.first() == Some(&0xff) {
return Err(buffa::DecodeError::InvalidFieldNumber);
}
Ok(Self { buf })
}
fn merge_lazy(
&mut self,
_buf: &'a [u8],
_ctx: buffa::DecodeContext<'_>,
) -> Result<(), buffa::DecodeError> {
unimplemented!("not exercised by these tests")
}
fn to_owned_message(&self) -> Result<Self::Owned, buffa::DecodeError> {
Ok(Block)
}
}
#[test]
fn it_decodes_a_lazy_view_borrowing_the_input() {
let bytes = vec![0x01, 0x02, 0x03];
let view = BlockLazyView::decode_lazy_slice(&bytes).expect("valid input");
assert_eq!(view.buf, &bytes[..], "the view borrows the input buffer");
}
#[test]
fn it_propagates_decode_errors() {
let bytes = vec![0xff];
assert!(BlockLazyView::decode_lazy_slice(&bytes).is_err());
}
}
pub fn register_panic_hook() {
#[cfg(target_arch = "wasm32")]
{
use std::sync::Once;
static SET_HOOK: Once = Once::new();
SET_HOOK.call_once(|| {
std::panic::set_hook(Box::new(hook));
});
}
}
#[cfg_attr(not(target_arch = "wasm32"), allow(unused))]
fn hook(info: &std::panic::PanicHookInfo<'_>) {
#[cfg(target_arch = "wasm32")]
{
let error_msg = info
.payload()
.downcast_ref::<String>()
.map(String::as_str)
.or_else(|| info.payload().downcast_ref::<&'static str>().copied())
.unwrap_or("");
let location = info.location();
unsafe {
let _ = match location {
Some(loc) => {
let file = loc.file();
let line = loc.line();
let column = loc.column();
externs::register_panic(
error_msg.as_ptr(),
error_msg.len() as u32,
file.as_ptr(),
file.len() as u32,
line,
column,
)
}
None => externs::register_panic(
error_msg.as_ptr(),
error_msg.len() as u32,
std::ptr::null(),
0,
0,
0,
),
};
}
}
}