#[cfg(feature = "async")]
pub mod async_client;
pub mod booster;
pub mod cache;
pub mod config;
pub mod connection;
pub mod error;
pub mod models;
pub mod queries;
pub mod sql_builder;
#[cfg(feature = "async")]
pub use async_client::AsyncMtgjsonSdk;
pub use cache::CacheManager;
pub use connection::Connection;
pub use error::{MtgjsonError, Result};
pub use sql_builder::SqlBuilder;
use std::collections::HashMap;
use std::fmt;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::time::Duration;
pub type ProgressCallback = Arc<dyn Fn(&str, u64, u64) + Send + Sync>;
pub struct MtgjsonSdkBuilder {
cache_dir: Option<PathBuf>,
offline: bool,
timeout: Duration,
on_progress: Option<ProgressCallback>,
}
impl Default for MtgjsonSdkBuilder {
fn default() -> Self {
Self {
cache_dir: None,
offline: false,
timeout: Duration::from_secs(120),
on_progress: None,
}
}
}
impl MtgjsonSdkBuilder {
pub fn cache_dir<P: AsRef<Path>>(mut self, path: P) -> Self {
self.cache_dir = Some(path.as_ref().to_path_buf());
self
}
pub fn offline(mut self, offline: bool) -> Self {
self.offline = offline;
self
}
pub fn timeout(mut self, timeout: Duration) -> Self {
self.timeout = timeout;
self
}
pub fn on_progress<F>(mut self, f: F) -> Self
where
F: Fn(&str, u64, u64) + Send + Sync + 'static,
{
self.on_progress = Some(Arc::new(f));
self
}
pub fn build(self) -> Result<MtgjsonSdk> {
let cache = CacheManager::new(
self.cache_dir,
self.offline,
self.timeout,
self.on_progress,
)?;
let conn = Connection::new(cache)?;
Ok(MtgjsonSdk { conn })
}
}
pub struct MtgjsonSdk {
conn: Connection,
}
impl MtgjsonSdk {
pub fn builder() -> MtgjsonSdkBuilder {
MtgjsonSdkBuilder::default()
}
pub fn cards(&self) -> queries::cards::CardQuery<'_> {
queries::cards::CardQuery::new(&self.conn)
}
pub fn sets(&self) -> queries::sets::SetQuery<'_> {
queries::sets::SetQuery::new(&self.conn)
}
pub fn tokens(&self) -> queries::tokens::TokenQuery<'_> {
queries::tokens::TokenQuery::new(&self.conn)
}
pub fn prices(&self) -> queries::prices::PriceQuery<'_> {
queries::prices::PriceQuery::new(&self.conn)
}
pub fn legalities(&self) -> queries::legalities::LegalityQuery<'_> {
queries::legalities::LegalityQuery::new(&self.conn)
}
pub fn identifiers(&self) -> queries::identifiers::IdentifierQuery<'_> {
queries::identifiers::IdentifierQuery::new(&self.conn)
}
pub fn decks(&self) -> queries::decks::DeckQuery<'_> {
queries::decks::DeckQuery::new(&self.conn)
}
pub fn sealed(&self) -> queries::sealed::SealedQuery<'_> {
queries::sealed::SealedQuery::new(&self.conn)
}
pub fn skus(&self) -> queries::skus::SkuQuery<'_> {
queries::skus::SkuQuery::new(&self.conn)
}
pub fn enums(&self) -> queries::enums::EnumQuery<'_> {
queries::enums::EnumQuery::new(&self.conn)
}
pub fn booster(&self) -> booster::BoosterSimulator<'_> {
booster::BoosterSimulator::new(&self.conn)
}
pub fn meta(&self) -> Result<serde_json::Value> {
self.conn.cache.borrow_mut().load_json("meta")
}
pub fn views(&self) -> Vec<String> {
self.conn.views()
}
pub fn sql(
&self,
query: &str,
params: &[String],
) -> Result<Vec<HashMap<String, serde_json::Value>>> {
self.conn.execute(query, params)
}
pub fn export_db<P: AsRef<Path>>(&self, path: P) -> Result<PathBuf> {
self.conn.export_db(path.as_ref())
}
#[cfg(feature = "polars")]
pub fn sql_df(
&self,
query: &str,
params: &[String],
) -> Result<polars::frame::DataFrame> {
self.conn.execute_df(query, params)
}
pub fn refresh(&self) -> Result<bool> {
let stale = self.conn.cache.borrow_mut().is_stale()?;
if stale {
self.conn.cache.borrow().clear()?;
self.conn.reset_views();
eprintln!("MTGJSON data was stale; cache cleared and views reset");
}
Ok(stale)
}
pub fn close(self) {
drop(self);
}
pub fn connection(&self) -> &Connection {
&self.conn
}
pub fn connection_mut(&mut self) -> &mut Connection {
&mut self.conn
}
}
impl fmt::Display for MtgjsonSdk {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let views = self.conn.views();
let cache = self.conn.cache.borrow();
write!(
f,
"MtgjsonSdk(cache_dir={}, views=[{}], offline={})",
cache.cache_dir.display(),
views.join(", "),
cache.offline
)
}
}