#![deny(missing_debug_implementations, missing_docs, clippy::undocumented_unsafe_blocks)]
use mountpoint_s3_crt_sys::*;
pub mod auth;
pub mod checksums;
pub mod common;
pub mod http;
pub mod io;
pub mod s3;
use std::ptr::NonNull;
use std::{ffi::OsStr, os::unix::prelude::OsStrExt};
use crate::common::error::Error;
pub(crate) mod private {
pub trait Sealed {}
}
pub(crate) trait ToAwsByteCursor {
unsafe fn as_aws_byte_cursor(&self) -> aws_byte_cursor;
}
impl<S: AsRef<OsStr>> ToAwsByteCursor for S {
unsafe fn as_aws_byte_cursor(&self) -> aws_byte_cursor {
self.as_ref().as_bytes().as_aws_byte_cursor()
}
}
impl ToAwsByteCursor for [u8] {
unsafe fn as_aws_byte_cursor(&self) -> aws_byte_cursor {
aws_byte_cursor {
ptr: self.as_ptr() as *mut _,
len: self.len(),
}
}
}
pub(crate) unsafe fn aws_byte_cursor_as_slice<'a>(cursor: &aws_byte_cursor) -> &'a [u8] {
if cursor.ptr.is_null() {
assert_eq!(cursor.len, 0, "length must be 0 for null cursors");
&[]
} else {
std::slice::from_raw_parts(cursor.ptr, cursor.len)
}
}
pub(crate) trait CrtError: Sized {
type Return;
unsafe fn ok_or_last_error(self) -> Result<Self::Return, Error>;
}
impl<T> CrtError for *const T {
type Return = NonNull<T>;
unsafe fn ok_or_last_error(self) -> Result<Self::Return, Error> {
NonNull::new(self as *mut T).ok_or_else(|| Error::last_error())
}
}
impl<T> CrtError for *mut T {
type Return = NonNull<T>;
unsafe fn ok_or_last_error(self) -> Result<Self::Return, Error> {
NonNull::new(self as *mut T).ok_or_else(|| Error::last_error())
}
}
impl CrtError for i32 {
type Return = ();
unsafe fn ok_or_last_error(self) -> Result<Self::Return, Error> {
match self {
AWS_OP_SUCCESS => Ok(()),
AWS_OP_ERR => Err(Error::last_error()),
n => Err(common::error::Error::from(n)),
}
}
}
pub(crate) trait ResultExt: Sized {
fn on_err<F>(self, f: F) -> Self
where
F: FnOnce();
}
impl<T, E> ResultExt for Result<T, E> {
fn on_err<F>(self, f: F) -> Result<T, E>
where
F: FnOnce(),
{
match self {
Ok(val) => Ok(val),
Err(err) => {
f();
Err(err)
}
}
}
}
#[cfg(test)]
mod test {
use crate::common::rust_log_adapter::RustLogAdapter;
#[ctor::ctor]
fn init_tracing_subscriber() {
RustLogAdapter::try_init().expect("unable to install CRT log adapter");
tracing_subscriber::fmt::init();
}
#[test]
#[ignore]
fn test_asan_working() {
use mountpoint_s3_crt_sys::{aws_byte_cursor, aws_byte_cursor_is_valid};
let heap_cursor = Box::new(aws_byte_cursor {
ptr: std::ptr::null_mut(),
len: 0,
});
let heap_ptr = &*heap_cursor as *const aws_byte_cursor as *mut _;
drop(heap_cursor);
let _ = unsafe { aws_byte_cursor_is_valid(heap_ptr) };
}
}