Skip to content

Commit

Permalink
Make read a service, move language from data to read
Browse files Browse the repository at this point in the history
  • Loading branch information
ackwell committed Jun 23, 2024
1 parent 92496c1 commit ccf272f
Show file tree
Hide file tree
Showing 17 changed files with 92 additions and 73 deletions.
4 changes: 2 additions & 2 deletions boilmaster.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ limit.depth = 2
# TODO: should this be shared with search eventually, or nah?
filter.exdschema.list = "Name,Singular,Icon"

[data]
language = "en"
[read.language]
default = "en"

[version]
interval = 3600 # 1 hour
Expand Down
26 changes: 3 additions & 23 deletions src/data/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,15 @@ use std::{
};

use anyhow::Context;
use ironworks::{
excel::{Excel, Language},
sqpack::SqPack,
zipatch, Ironworks,
};
use serde::Deserialize;
use ironworks::{excel::Excel, sqpack::SqPack, zipatch, Ironworks};
use tokio::{select, sync::watch};
use tokio_util::sync::CancellationToken;

use crate::version::{self, VersionKey};

use super::{
error::{Error, Result},
language::LanguageString,
};

#[derive(Debug, Deserialize)]
pub struct Config {
language: LanguageString,
}
use super::error::{Error, Result};

pub struct Data {
default_language: Language,

channel: watch::Sender<Vec<VersionKey>>,

// Root ZiPatch instance, acts as a LUT cache
Expand All @@ -37,11 +22,10 @@ pub struct Data {
}

impl Data {
pub fn new(config: Config) -> Self {
pub fn new() -> Self {
let (sender, _receiver) = watch::channel(vec![]);

Data {
default_language: config.language.into(),
channel: sender,
zipatch: zipatch::ZiPatch::new().with_persisted_lookups(),
versions: Default::default(),
Expand All @@ -54,10 +38,6 @@ impl Data {
self.versions.read().expect("poisoned").len() > 0
}

pub fn default_language(&self) -> Language {
self.default_language
}

pub fn subscribe(&self) -> watch::Receiver<Vec<VersionKey>> {
self.channel.subscribe()
}
Expand Down
3 changes: 0 additions & 3 deletions src/data/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ pub enum Error {
#[error("unknown version {0}")]
UnknownVersion(VersionKey),

#[error("unknown language \"{0}\"")]
UnknownLanguage(String),

#[error(transparent)]
Failure(#[from] anyhow::Error),
}
Expand Down
4 changes: 1 addition & 3 deletions src/data/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
mod data;
mod error;
mod language;

pub use {
data::{Config, Data, Version},
data::{Data, Version},
error::Error,
language::LanguageString,
};
4 changes: 2 additions & 2 deletions src/http/api1/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl From<data::Error> for Error {
fn from(error: data::Error) -> Self {
use data::Error as DE;
match error {
DE::UnknownVersion(..) | DE::UnknownLanguage(..) => Self::Invalid(error.to_string()),
DE::UnknownVersion(..) => Self::Invalid(error.to_string()),
DE::Failure(inner) => Self::Other(inner),
}
}
Expand All @@ -59,7 +59,7 @@ impl From<read::Error> for Error {
use read::Error as RE;
match error {
RE::NotFound(..) => Self::NotFound(error.to_string()),
RE::FilterSchemaMismatch(..) | RE::SchemaGameMismatch(..) => {
RE::FilterSchemaMismatch(..) | RE::SchemaGameMismatch(..) | RE::InvalidLanguage(..) => {
Self::Invalid(error.to_string())
}
RE::Failure(inner) => Self::Other(inner),
Expand Down
4 changes: 2 additions & 2 deletions src/http/api1/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use nom::{
use schemars::JsonSchema;
use serde::{de, Deserialize};

use crate::{data, read};
use crate::read;

use super::error;

Expand Down Expand Up @@ -196,7 +196,7 @@ fn index(input: &str) -> IResult<&str, Entry> {
fn language(input: &str) -> IResult<&str, excel::Language> {
map_res(alphanumeric1, |string: &str| {
string
.parse::<data::LanguageString>()
.parse::<read::LanguageString>()
.map(excel::Language::from)
})(input)
}
Expand Down
15 changes: 8 additions & 7 deletions src/http/api1/sheet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ use schemars::{
use serde::{de, Deserialize, Deserializer, Serialize};

use crate::{
data::LanguageString,
http::service,
read, schema,
utility::{anyhow::Anyhow, jsonschema::impl_jsonschema},
Expand Down Expand Up @@ -145,7 +144,7 @@ fn rowspecifier_schema(_generator: &mut SchemaGenerator) -> Schema {
struct SheetQuery {
// Data resolution
/// Language to use for data with no language otherwise specified in the fields filter.
language: Option<LanguageString>,
language: Option<read::LanguageString>,

/// Schema that row data should be read with.
schema: Option<schema::Specifier>,
Expand Down Expand Up @@ -247,6 +246,7 @@ async fn sheet(
VersionQuery(version_key): VersionQuery,
Query(query): Query<SheetQuery>,
State(data): State<service::Data>,
State(read): State<service::Read>,
State(schema_provider): State<service::Schema>,
Extension(config): Extension<Config>,
) -> Result<impl IntoApiResponse> {
Expand All @@ -256,7 +256,7 @@ async fn sheet(
let language = query
.language
.map(excel::Language::from)
.unwrap_or_else(|| data.default_language());
.unwrap_or_else(|| read.default_language());

// TODO: Consider extractor for this.
let schema_specifier = schema_provider.canonicalize(query.schema, version_key)?;
Expand Down Expand Up @@ -318,7 +318,7 @@ async fn sheet(

// TODO: This is pretty wasteful to call inside a loop, revisit actual read logic.
// TODO: at the moment, an unknown row specifier will cause excel to error with a NotFound (which is fine), however read:: then squashes that with anyhow, meaning the error gets hidden in a 500 ISE. revisit error handling in read:: while i'm at it ref. the above.
let fields = read::read(
let fields = read.read(
&excel,
schema.as_ref(),
&path.sheet,
Expand Down Expand Up @@ -362,7 +362,7 @@ struct RowPath {
#[derive(Deserialize, JsonSchema)]
struct RowQuery {
/// Language to use for data with no language otherwise specified in the fields filter.
language: Option<LanguageString>,
language: Option<read::LanguageString>,

/// Schema that row data should be read with.
schema: Option<schema::Specifier>,
Expand Down Expand Up @@ -422,6 +422,7 @@ async fn row(
VersionQuery(version_key): VersionQuery,
Query(query): Query<RowQuery>,
State(data): State<service::Data>,
State(read): State<service::Read>,
State(schema_provider): State<service::Schema>,
Extension(config): Extension<Config>,
) -> Result<impl IntoApiResponse> {
Expand All @@ -430,7 +431,7 @@ async fn row(
let language = query
.language
.map(excel::Language::from)
.unwrap_or_else(|| data.default_language());
.unwrap_or_else(|| read.default_language());

let schema_specifier = schema_provider.canonicalize(query.schema, version_key)?;

Expand All @@ -450,7 +451,7 @@ async fn row(
let row_id = path.row.row_id;
let subrow_id = path.row.subrow_id;

let fields = read::read(
let fields = read.read(
&excel,
schema.as_ref(),
&path.sheet,
Expand Down
4 changes: 2 additions & 2 deletions src/http/api1/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use schemars::{
};
use serde::ser::{Serialize, SerializeMap, SerializeSeq, SerializeStruct};

use crate::{data, read, utility::jsonschema::impl_jsonschema};
use crate::{read, utility::jsonschema::impl_jsonschema};

#[derive(Debug)]
pub struct ValueString(pub read::Value, pub excel::Language);
Expand Down Expand Up @@ -155,7 +155,7 @@ impl ValueReference<'_> {
.map(|(read::StructKey { name, language }, value)| {
let key = match *language == self.language {
true => name.to_owned(),
false => format!("{name}@{}", data::LanguageString::from(*language)),
false => format!("{name}@{}", read::LanguageString::from(*language)),
};

(key, value)
Expand Down
4 changes: 3 additions & 1 deletion src/http/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ pub struct Config {
pub async fn serve(
cancel: CancellationToken,
config: Config,
data: service::Data,
asset: service::Asset,
data: service::Data,
read: service::Read,
schema: service::Schema,
// search: service::Search,
version: service::Version,
Expand All @@ -49,6 +50,7 @@ pub async fn serve(
.with_state(service::State {
asset,
data,
read,
schema,
// search,
version,
Expand Down
3 changes: 3 additions & 0 deletions src/http/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ use axum::extract::FromRef;
use crate::{
asset,
data,
read,
schema,
// search,
version,
};

pub type Asset = Arc<asset::Service>;
pub type Data = Arc<data::Data>;
pub type Read = Arc<read::Read>;
pub type Schema = Arc<schema::Provider>;
// pub type Search = Arc<search::Search>;
pub type Version = Arc<version::Manager>;
Expand All @@ -20,6 +22,7 @@ pub type Version = Arc<version::Manager>;
pub struct State {
pub asset: Asset,
pub data: Data,
pub read: Read,
pub schema: Schema,
// pub search: Search,
pub version: Version,
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
pub mod asset;
pub mod data;
pub mod http;
mod read;
pub mod read;
pub mod schema;
// pub mod search;
pub mod tracing;
Expand Down
9 changes: 6 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use boilmaster::{
asset,
data,
http,
read,
schema,
// search,
tracing,
Expand All @@ -23,7 +24,7 @@ use tokio_util::sync::CancellationToken;
struct Config {
// tracing: tracing::Config, - read individually.
http: http::Config,
data: data::Config,
read: read::Config,
version: version::Config,
schema: schema::Config,
// search: search::Config,
Expand Down Expand Up @@ -54,8 +55,9 @@ async fn main() -> anyhow::Result<()> {
let version = Arc::new(
version::Manager::new(config.version).context("failed to create version manager")?,
);
let data = Arc::new(data::Data::new(config.data));
let data = Arc::new(data::Data::new());
let asset = Arc::new(asset::Service::new(data.clone()));
let read = Arc::new(read::Read::new(config.read));
let schema = Arc::new(
schema::Provider::new(config.schema, data.clone())
.context("failed to create schema provider")?,
Expand All @@ -78,8 +80,9 @@ async fn main() -> anyhow::Result<()> {
http::serve(
shutdown_token,
config.http,
data.clone(),
asset,
data.clone(),
read,
schema.clone(),
// search.clone(),
version.clone(),
Expand Down
3 changes: 3 additions & 0 deletions src/read/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ pub enum Error {
#[error("{0}")]
NotFound(String),

#[error("invalid or unsupported language \"{0}\"")]
InvalidLanguage(String),

/// The provided filter does not map cleanly onto the sheet schema.
#[error("filter <-> schema mismatch on {}: {}", .0.field, .0.reason)]
FilterSchemaMismatch(MismatchError),
Expand Down
1 change: 1 addition & 0 deletions src/read/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub enum Filter {
All,
}

// TODO: Merge with LanguageString?
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Language(pub excel::Language);
impl IsEnabled for Language {}
2 changes: 1 addition & 1 deletion src/data/language.rs → src/read/language.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ impl FromStr for LanguageString {
"chs" => Language::ChineseSimplified,
"cht" => Language::ChineseTraditional,
"kr" => Language::Korean,
_ => return Err(Error::UnknownLanguage(string.into())),
_ => return Err(Error::InvalidLanguage(string.into())),
};

Ok(Self(language))
Expand Down
4 changes: 3 additions & 1 deletion src/read/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
mod error;
mod filter;
mod language;
mod read;
mod value;

pub use {
error::Error,
filter::{Filter, Language},
read::read,
language::LanguageString,
read::{Config, Read},
value::{Reference, StructKey, Value},
};
Loading

0 comments on commit ccf272f

Please sign in to comment.