pub mod bwt;
pub mod context;
pub mod lcp;
pub mod plcp;
pub mod suffix_array;
pub mod typestate;
pub mod unbwt;
mod generics_dispatch;
mod owned_or_borrowed;
use bytemuck::Pod;
use num_traits::{NumCast, PrimInt};
use std::fmt::{Debug, Display};
use generics_dispatch::{
LibsaisFunctionsLargeAlphabet, LibsaisFunctionsSmallAlphabet, LibsaisLcpFunctions,
OutputDispatch,
};
use sealed::Sealed;
use typestate::OutputElementOrUndecided;
pub use libsais_sys::libsais::LIBSAIS_VERSION_STRING;
pub const LIBSAIS_I32_OUTPUT_MAXIMUM_SIZE: usize = 2147483647;
pub const LIBSAIS_I64_OUTPUT_MAXIMUM_SIZE: usize = 9223372036854775807;
#[doc(inline)]
pub use {
bwt::BwtConstruction, lcp::LcpConstruction, plcp::PlcpConstruction,
suffix_array::SuffixArrayConstruction, unbwt::UnBwt,
};
pub trait InputElement: Sealed + PrimInt + Debug + Display + Send + Sync + Pod + 'static {
const RECOMMENDED_EXTRA_SPACE: usize;
type SingleThreadedOutputDispatcher<O: OutputElementOrUndecided>: OutputDispatch<Self, O>;
#[cfg(feature = "openmp")]
type MultiThreadedOutputDispatcher<O: OutputElementOrUndecided>: OutputDispatch<Self, O>;
}
pub trait OutputElement: Sealed + PrimInt + Debug + Display + Send + Sync + Pod + 'static {
type SingleThreaded8InputFunctions: LibsaisFunctionsSmallAlphabet<u8, Self>
+ LibsaisLcpFunctions<u8, Self>;
type SingleThreaded16InputFunctions: LibsaisFunctionsSmallAlphabet<u16, Self>
+ LibsaisLcpFunctions<u16, Self>;
type SingleThreaded32InputFunctions: LibsaisFunctionsLargeAlphabet<i32, Self>
+ LibsaisLcpFunctions<i32, Self>;
type SingleThreaded64InputFunctions: LibsaisFunctionsLargeAlphabet<i64, Self>
+ LibsaisLcpFunctions<i64, Self>;
#[cfg(feature = "openmp")]
type MultiThreaded8InputFunctions: LibsaisFunctionsSmallAlphabet<u8, Self>
+ LibsaisLcpFunctions<u8, Self>;
#[cfg(feature = "openmp")]
type MultiThreaded16InputFunctions: LibsaisFunctionsSmallAlphabet<u16, Self>
+ LibsaisLcpFunctions<u16, Self>;
#[cfg(feature = "openmp")]
type MultiThreaded32InputFunctions: LibsaisFunctionsLargeAlphabet<i32, Self>
+ LibsaisLcpFunctions<i32, Self>;
#[cfg(feature = "openmp")]
type MultiThreaded64InputFunctions: LibsaisFunctionsLargeAlphabet<i64, Self>
+ LibsaisLcpFunctions<i64, Self>;
}
pub trait SmallAlphabet: InputElement {
const FREQUENCY_TABLE_SIZE: usize;
}
pub trait LargeAlphabet: InputElement + OutputElement {}
pub trait IsValidOutputFor<I: InputElement>: Sealed + OutputElement {}
impl<O: OutputElement> IsValidOutputFor<u8> for O {}
impl<O: OutputElement> IsValidOutputFor<u16> for O {}
impl IsValidOutputFor<i32> for i32 {}
impl IsValidOutputFor<i64> for i64 {}
pub trait SupportsPlcpOutputFor<I: InputElement>:
Sealed + OutputElement + IsValidOutputFor<I>
{
}
impl<O: OutputElement> SupportsPlcpOutputFor<u8> for O {}
impl<O: OutputElement> SupportsPlcpOutputFor<u16> for O {}
impl SupportsPlcpOutputFor<i32> for i32 {}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LibsaisError {
InvalidInput,
OutOfMemory,
UnknownError,
}
impl LibsaisError {
fn from_return_code<O: OutputElement>(return_code: O) -> Self {
let return_code_i64 = <i64 as NumCast>::from(return_code).unwrap();
match return_code_i64 {
0 => panic!("Return code does not indicate an error"),
-1 => Self::InvalidInput,
-2 => Self::OutOfMemory,
_ => Self::UnknownError,
}
}
}
impl Display for LibsaisError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
<LibsaisError as Debug>::fmt(self, f)
}
}
impl std::error::Error for LibsaisError {}
pub(crate) trait IntoSaisResult {
fn into_empty_sais_result(self) -> Result<(), LibsaisError>;
fn into_primary_index_sais_result(self) -> Result<usize, LibsaisError>;
}
impl<O: OutputElement> IntoSaisResult for O {
fn into_empty_sais_result(self) -> Result<(), LibsaisError> {
if self != O::zero() {
Err(LibsaisError::from_return_code(self))
} else {
Ok(())
}
}
fn into_primary_index_sais_result(self) -> Result<usize, LibsaisError> {
if self < O::zero() {
Err(LibsaisError::from_return_code(self))
} else {
Ok(<usize as NumCast>::from(self).unwrap())
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ThreadCount {
pub(crate) value: u16,
}
impl ThreadCount {
pub const fn fixed(thread_count: u16) -> Self {
if thread_count == 0 {
panic!("Fixed thread count cannot be 0");
}
Self {
value: thread_count,
}
}
pub const fn openmp_default() -> Self {
Self { value: 0 }
}
}
mod sealed {
pub trait Sealed {}
}