95 lines
2.2 KiB
Rust
95 lines
2.2 KiB
Rust
// Remember that Server functions parameters must not be references.
|
|
// They are coming from potentially other computers.
|
|
//
|
|
// Server functions must be:
|
|
// * Be an async function
|
|
// * Have arguments and a return type that both implement serialize and deserialize (with serde).
|
|
// * Return a Result with an error type of ServerFnError
|
|
|
|
#[cfg(feature = "server")]
|
|
use std::sync::Arc;
|
|
|
|
use dioxus::prelude::*;
|
|
|
|
#[cfg(feature = "server")]
|
|
use tokio::sync::OnceCell;
|
|
|
|
use tavern::{Adventurer, Lore, Tale};
|
|
|
|
#[cfg(feature = "server")]
|
|
use tavern::Database;
|
|
|
|
|
|
|
|
#[cfg(feature = "server")]
|
|
static BLOG_DATABASE: OnceCell<Arc<Database>> = OnceCell::const_new();
|
|
|
|
|
|
|
|
#[cfg(feature = "server")]
|
|
async fn get_database_instance<P>(path: P) -> Result<&'static Arc<Database>, ServerFnError>
|
|
where P: AsRef<std::path::Path>
|
|
{
|
|
BLOG_DATABASE.get_or_try_init(|| async
|
|
{
|
|
let db = Database::open(path).await
|
|
.map_err(|e| ServerFnError::new(format!("Failed to open database: {}", e)))?;
|
|
|
|
Ok(Arc::new(db))
|
|
}).await
|
|
}
|
|
|
|
#[cfg(feature = "server")]
|
|
pub async fn init_database<P>(path: P) -> Result<(), ServerFnError>
|
|
where P: AsRef<std::path::Path>
|
|
{
|
|
match get_database_instance(path).await
|
|
{
|
|
Ok(_) => { Ok(()) }
|
|
Err(e) => { Err(e) }
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "server")]
|
|
async fn get_database() -> Result<&'static Arc<Database>, ServerFnError>
|
|
{
|
|
get_database_instance("tavern.db").await
|
|
}
|
|
|
|
|
|
|
|
#[server]
|
|
pub async fn get_blog_list(categories: Vec<String>) -> Result<Vec<Lore>, ServerFnError>
|
|
{
|
|
let db = get_database().await?;
|
|
|
|
let summaries = db.get_tales_summary(&categories).await
|
|
.map_err(|e| ServerFnError::new(e))?;
|
|
|
|
Ok(summaries)
|
|
}
|
|
|
|
|
|
#[server]
|
|
pub async fn get_blog_post(slug: String) -> Result<Tale, ServerFnError>
|
|
{
|
|
let db = get_database().await?;
|
|
|
|
let tale = db.get_tale_by_slug(&slug).await
|
|
.map_err(|e| ServerFnError::new(e))?;
|
|
|
|
tale.ok_or(ServerFnError::new(format!("Post {} not found", slug)))
|
|
}
|
|
|
|
|
|
#[server]
|
|
pub async fn get_author(handle: String) -> Result<Adventurer, ServerFnError>
|
|
{
|
|
let db = get_database().await?;
|
|
|
|
let author = db.get_adventurer(&handle).await
|
|
.map_err(|e| ServerFnError::new(e))?;
|
|
|
|
author.ok_or(ServerFnError::new(format!("Author {} not found.", handle)))
|
|
}
|