use std::sync::Arc;
use manas_http::{
header::common::qvalue::QValue,
representation::impl_::{binary::BinaryRepresentation, common::data::bytes_inmem::BytesInmem},
uri::invariant::AbsoluteHttpUri,
};
use manas_repo_layers::dconneging::conneg_layer::{
impl_::{
constant_overriding::{
ConstantOverrideNegotiationConfig, ConstantOverrideNegotiationLayer,
ConstantOverridingPreferences,
},
stack::StackConfig,
},
DerivedContentNegotiationLayer,
};
use manas_repo_opendal::service::resource_operator::reader::ODRResourceReader;
use once_cell::sync::Lazy;
use tower::layer::util::Stack;
use upon::Engine;
use crate::repo::{RcpBaseRepo, RcpBaseRepoSetup, RcpRdfSourceCNL};
static DATABROWSER_TEMPLATE_ENGINE: Lazy<Engine> = Lazy::new(|| {
let mut engine = Engine::new();
engine
.add_template(
"databrowser",
include_str!("../templates/databrowser.html.template"),
)
.expect("Template must be valid.");
engine
});
#[derive(serde::Serialize)]
pub struct DatabrowserContext {
pub mashlib_js_uri: AbsoluteHttpUri,
pub mashlib_css_uri: AbsoluteHttpUri,
}
impl DatabrowserContext {
pub fn new_from_unpkg() -> Self {
Self {
mashlib_js_uri: "https://www.unpkg.com/mashlib/dist/mashlib.min.js"
.parse()
.unwrap(),
mashlib_css_uri: "https://www.unpkg.com/mashlib/dist/mash.css"
.parse()
.unwrap(),
}
}
}
pub fn resolve_databrowser_content(context: DatabrowserContext) -> BytesInmem {
DATABROWSER_TEMPLATE_ENGINE
.get_template("databrowser")
.expect("Template must exist")
.render(&context)
.to_string()
.expect("Must be valid")
.into()
}
pub type DatabrowserAdaptedCNL<Backend, Inner> = Stack<
Inner,
ConstantOverrideNegotiationLayer<
RcpBaseRepo<Backend>,
<Inner as DerivedContentNegotiationLayer<
RcpBaseRepo<Backend>,
BinaryRepresentation,
ODRResourceReader<RcpBaseRepoSetup<Backend>>,
>>::WService,
>,
>;
pub type RcpDatabrowserAdaptedRdfSourceCNL<Backend> =
DatabrowserAdaptedCNL<Backend, RcpRdfSourceCNL<Backend>>;
pub fn adapt_dconneg_layer_config<InnerConfig>(
inner_config: Arc<InnerConfig>,
opt_databrowser_context: Option<DatabrowserContext>,
) -> Arc<StackConfig<InnerConfig, Option<ConstantOverrideNegotiationConfig>>> {
let overrider_config = opt_databrowser_context.map(|databrowser_context| {
ConstantOverrideNegotiationConfig {
constant_rep_content_type: mime::TEXT_HTML.try_into().expect("Must be valid"),
constant_rep_complete_data: resolve_databrowser_content(databrowser_context),
overriding_preferences: Arc::new(ConstantOverridingPreferences {
min_quality: QValue::ZERO,
enabled_src_media_ranges: vec![mime::STAR_STAR],
disabled_src_media_ranges: vec![],
}),
}
});
Arc::new(StackConfig {
inner_config,
outer_config: Arc::new(overrider_config),
})
}