use crate::migration::set::MigrationSet;
use crate::store::StorageResult;
use crate::store::builder::Backend;
#[cfg(any(feature = "json", feature = "toml", feature = "ron"))]
use crate::store::config::FileWritePolicy;
use crate::store::config::StoreConfig;
#[cfg(any(feature = "json", feature = "toml", feature = "ron"))]
use crate::store::opening::WhenItWillNotRead;
use crate::{MigrationReport, Store};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Engine {
backend: Backend,
settings: Settings,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Settings {
Defaults,
#[cfg(feature = "redb")]
Redb(Redb),
#[cfg(any(feature = "json", feature = "toml", feature = "ron"))]
Text(TextSettings),
#[cfg(feature = "memory")]
Memory(Memory),
}
impl Engine {
pub const fn backend(&self) -> Backend {
self.backend
}
pub fn open(
self,
mut config: StoreConfig,
mset: MigrationSet,
) -> StorageResult<(Store, MigrationReport)> {
self.settle(&mut config);
self.backend.open(config, mset)
}
fn settle(self, config: &mut StoreConfig) {
match (self.settings, config) {
(Settings::Defaults, _) => {}
#[cfg(feature = "redb")]
(Settings::Redb(redb), config) => {
config.redb_cache_size = redb.cache_size;
config.parallel_reads = redb.parallel_reads;
}
#[cfg(any(feature = "json", feature = "toml", feature = "ron"))]
(Settings::Text(text), config) => {
config.file_write = text.file_write;
config.will_not_read = text.will_not_read;
}
#[cfg(feature = "memory")]
(Settings::Memory(memory), config) => {
config.parallel_reads = memory.parallel_reads;
}
}
}
}
impl From<Backend> for Engine {
fn from(backend: Backend) -> Self {
Self {
backend,
settings: Settings::Defaults,
}
}
}
#[cfg(feature = "redb")]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct Redb {
cache_size: usize,
parallel_reads: bool,
}
#[cfg(feature = "redb")]
impl Redb {
pub const fn new() -> Self {
Self {
cache_size: 0,
parallel_reads: false,
}
}
pub const fn cache_size(mut self, bytes: usize) -> Self {
self.cache_size = bytes;
self
}
pub const fn parallel_reads(mut self, yes: bool) -> Self {
self.parallel_reads = yes;
self
}
}
#[cfg(feature = "redb")]
impl From<Redb> for Engine {
fn from(redb: Redb) -> Self {
Self {
backend: Backend::Redb,
settings: Settings::Redb(redb),
}
}
}
#[cfg(feature = "memory")]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct Memory {
parallel_reads: bool,
}
#[cfg(feature = "memory")]
impl Memory {
pub const fn new() -> Self {
Self {
parallel_reads: false,
}
}
pub const fn parallel_reads(mut self, yes: bool) -> Self {
self.parallel_reads = yes;
self
}
}
#[cfg(feature = "memory")]
impl From<Memory> for Engine {
fn from(memory: Memory) -> Self {
Self {
backend: Backend::Memory,
settings: Settings::Memory(memory),
}
}
}
#[cfg(any(feature = "json", feature = "toml", feature = "ron"))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
struct TextSettings {
file_write: FileWritePolicy,
will_not_read: WhenItWillNotRead,
}
#[cfg(any(feature = "json", feature = "toml", feature = "ron"))]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Text {
backend: Backend,
settings: TextSettings,
}
#[cfg(any(feature = "json", feature = "toml", feature = "ron"))]
impl Text {
#[cfg(feature = "json")]
pub fn json() -> Self {
Self::of(Backend::Json)
}
#[cfg(feature = "toml")]
pub fn toml() -> Self {
Self::of(Backend::Toml)
}
#[cfg(feature = "ron")]
pub fn ron() -> Self {
Self::of(Backend::Ron)
}
fn of(backend: Backend) -> Self {
Self {
backend,
settings: TextSettings::default(),
}
}
pub fn file_write(
mut self,
configure: impl FnOnce(FileWritePolicy) -> FileWritePolicy,
) -> Self {
self.settings.file_write = configure(self.settings.file_write);
self
}
pub fn when_it_will_not_read(mut self, rule: WhenItWillNotRead) -> Self {
self.settings.will_not_read = rule;
self
}
}
#[cfg(any(feature = "json", feature = "toml", feature = "ron"))]
impl TryFrom<Backend> for Text {
type Error = Backend;
fn try_from(backend: Backend) -> Result<Self, Backend> {
match backend {
#[cfg(feature = "json")]
Backend::Json => Ok(Self::of(backend)),
#[cfg(feature = "toml")]
Backend::Toml => Ok(Self::of(backend)),
#[cfg(feature = "ron")]
Backend::Ron => Ok(Self::of(backend)),
#[allow(unreachable_patterns)]
other => Err(other),
}
}
}
#[cfg(any(feature = "json", feature = "toml", feature = "ron"))]
impl From<Text> for Engine {
fn from(text: Text) -> Self {
Self {
backend: text.backend,
settings: Settings::Text(text.settings),
}
}
}