use super::{EventBus, RuntimeBuilder, RuntimeInner};
use crate::{CacheType, DataSource, ProgressHandle, SharedTileSource};
use anyhow::Result;
use std::{path::Path, sync::Arc};
#[derive(Clone)]
pub struct TilesRuntime {
pub(crate) inner: Arc<RuntimeInner>,
}
impl TilesRuntime {
#[must_use]
pub fn new() -> Self {
Self::builder().build()
}
#[must_use]
pub fn new_silent() -> Self {
Self::builder().silent_progress(true).build()
}
#[must_use]
pub fn builder() -> RuntimeBuilder {
RuntimeBuilder::default()
}
#[must_use]
pub fn cache_type(&self) -> &CacheType {
&self.inner.cache_type
}
#[must_use]
pub fn events(&self) -> &EventBus {
&self.inner.event_bus
}
#[must_use]
pub fn create_progress(&self, message: &str, total: u64) -> ProgressHandle {
self.inner.progress_factory.lock().unwrap().create(message, total)
}
pub async fn write_to_path(&self, reader: SharedTileSource, path: &Path) -> Result<()> {
self.inner.registry.write_to_path(reader, path, self.clone()).await
}
pub async fn get_reader_from_str(&self, filename: &str) -> Result<SharedTileSource> {
self.inner.registry.get_reader_from_str(filename, self.clone()).await
}
pub async fn get_reader(&self, data_source: DataSource) -> Result<SharedTileSource> {
self.inner.registry.get_reader(data_source, self.clone()).await
}
}
impl Default for TilesRuntime {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use crate::Event;
use super::*;
#[test]
fn test_runtime_creation() {
let runtime = TilesRuntime::new();
assert_eq!(runtime.cache_type(), &CacheType::InMemory);
}
#[test]
fn test_runtime_builder() {
let runtime = TilesRuntime::builder()
.with_memory_cache()
.silent_progress(true)
.build();
assert_eq!(runtime.cache_type(), &CacheType::InMemory);
}
#[test]
fn test_event_bus() {
let runtime = TilesRuntime::new();
let events = Arc::new(std::sync::Mutex::new(Vec::new()));
let events_clone = events.clone();
runtime.events().subscribe(move |event| {
events_clone.lock().unwrap().push(format!("{event:?}"));
});
runtime.events().step("Test step".to_string());
runtime.events().warn("Test warning".to_string());
runtime.events().error("Test error".to_string());
let captured = events.lock().unwrap();
assert_eq!(captured.len(), 3);
assert!(captured[0].contains("Step"));
assert!(captured[1].contains("Warning"));
assert!(captured[2].contains("Error"));
}
#[test]
fn test_progress_handle() {
let runtime = TilesRuntime::new();
let events = Arc::new(std::sync::Mutex::new(Vec::new()));
let events_clone = events.clone();
runtime.events().subscribe(move |event| {
if matches!(event, Event::Progress { .. }) {
events_clone.lock().unwrap().push(());
}
});
let progress = runtime.create_progress("Test", 100);
progress.set_position(50);
progress.inc(25);
progress.finish();
let captured = events.lock().unwrap();
assert!(captured.len() >= 2);
}
#[test]
fn test_runtime_clone() {
let runtime = TilesRuntime::new();
let runtime2 = runtime.clone();
let events = Arc::new(std::sync::Mutex::new(Vec::new()));
let events_clone = events.clone();
runtime.events().subscribe(move |_event| {
events_clone.lock().unwrap().push(());
});
runtime2.events().step("Test".to_string());
let captured = events.lock().unwrap();
assert_eq!(captured.len(), 1);
}
}