rewrite templates to use compile-time formatting
This commit is contained in:
parent
f4f82ed4b4
commit
291b440f81
10 changed files with 59 additions and 65 deletions
|
|
@ -195,11 +195,11 @@ pub fn make_router(
|
||||||
.route("/description.xml", get(description_xml))
|
.route("/description.xml", get(description_xml))
|
||||||
.route(
|
.route(
|
||||||
"/scpd/ContentDirectory.xml",
|
"/scpd/ContentDirectory.xml",
|
||||||
get(|| async { include_str!("resources/scpd_content_directory.xml") }),
|
get(|| async { include_str!("resources/templates/content_directory/scpd.xml") }),
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/scpd/ConnectionManager.xml",
|
"/scpd/ConnectionManager.xml",
|
||||||
get(|| async { include_str!("resources/scpd_connection_manager.xml") }),
|
get(|| async { include_str!("resources/templates/connection_manager/scpd.xml") }),
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/control/ContentDirectory",
|
"/control/ContentDirectory",
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,11 @@
|
||||||
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||||
<s:Body>
|
<s:Body>
|
||||||
<u:BrowseResponse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1">
|
<u:BrowseResponse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1">
|
||||||
<Result><![CDATA[{result}]]></Result>
|
<Result><![CDATA[<DIDL-Lite xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/">
|
||||||
|
{items}
|
||||||
|
</DIDL-Lite>]]></Result>
|
||||||
<NumberReturned>{number_returned}</NumberReturned>
|
<NumberReturned>{number_returned}</NumberReturned>
|
||||||
<TotalMatches>{total_matches}</TotalMatches>
|
<TotalMatches>{total_matches}</TotalMatches>
|
||||||
<UpdateID>{update_id}</UpdateID>
|
<UpdateID>{update_id}</UpdateID>
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
<DIDL-Lite xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/">
|
|
||||||
{items}
|
|
||||||
</DIDL-Lite>
|
|
||||||
|
|
@ -9,23 +9,19 @@ pub struct RootDescriptionInputs<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_root_description_xml(input: &RootDescriptionInputs<'_>) -> String {
|
pub fn render_root_description_xml(input: &RootDescriptionInputs<'_>) -> String {
|
||||||
let tmpl = include_str!("resources/templates/root_desc.tmpl.xml").trim();
|
format!(
|
||||||
|
include_str!("resources/templates/root_desc.tmpl.xml"),
|
||||||
// This isn't great perf-wise but whatever.
|
friendly_name = input.friendly_name,
|
||||||
tmpl.replace("{friendly_name}", input.friendly_name)
|
manufacturer = input.manufacturer,
|
||||||
.replace("{manufacturer}", input.manufacturer)
|
model_name = input.model_name,
|
||||||
.replace("{model_name}", input.model_name)
|
unique_id = input.unique_id,
|
||||||
.replace("{unique_id}", input.unique_id)
|
http_prefix = input.http_prefix
|
||||||
.replace("{http_prefix}", input.http_prefix)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_content_directory_browse(items: impl IntoIterator<Item = ItemOrContainer>) -> String {
|
pub fn render_content_directory_browse(items: impl IntoIterator<Item = ItemOrContainer>) -> String {
|
||||||
fn item_or_container(item_or_container: &ItemOrContainer) -> Option<String> {
|
fn item_or_container(item_or_container: &ItemOrContainer) -> Option<String> {
|
||||||
fn item(item: &Item) -> Option<String> {
|
fn item(item: &Item) -> Option<String> {
|
||||||
let tmpl =
|
|
||||||
include_str!("resources/templates/content_directory_control_browse_item.tmpl.xml")
|
|
||||||
.trim();
|
|
||||||
|
|
||||||
let mime = item.mime_type.as_ref()?;
|
let mime = item.mime_type.as_ref()?;
|
||||||
let upnp_class = match mime.type_().as_str() {
|
let upnp_class = match mime.type_().as_str() {
|
||||||
"video" => "object.item.videoItem",
|
"video" => "object.item.videoItem",
|
||||||
|
|
@ -33,31 +29,31 @@ pub fn render_content_directory_browse(items: impl IntoIterator<Item = ItemOrCon
|
||||||
};
|
};
|
||||||
let mime = mime.to_string();
|
let mime = mime.to_string();
|
||||||
|
|
||||||
Some(
|
Some(format!(
|
||||||
tmpl.replace("{id}", &item.id.to_string())
|
include_str!("resources/templates/content_directory/control/browse/item.tmpl.xml"),
|
||||||
.replace("{parent_id}", &item.parent_id.unwrap_or(0).to_string())
|
id = item.id,
|
||||||
.replace("{mime_type}", &mime)
|
parent_id = item.parent_id.unwrap_or(0),
|
||||||
.replace("{url}", &item.url)
|
mime_type = mime,
|
||||||
.replace("{upnp_class}", upnp_class)
|
url = item.url,
|
||||||
.replace("{title}", &item.title),
|
upnp_class = upnp_class,
|
||||||
)
|
title = item.title
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn container(item: &Container) -> String {
|
fn container(item: &Container) -> String {
|
||||||
let tmpl = include_str!(
|
let child_count_tag = match item.children_count {
|
||||||
"resources/templates/content_directory_control_browse_container.tmpl.xml"
|
Some(cc) => format!("childCount=\"{}\"", cc),
|
||||||
|
None => String::new(),
|
||||||
|
};
|
||||||
|
format!(
|
||||||
|
include_str!(
|
||||||
|
"resources/templates/content_directory/control/browse/container.tmpl.xml"
|
||||||
|
),
|
||||||
|
id = item.id,
|
||||||
|
parent_id = item.parent_id.unwrap_or(0),
|
||||||
|
title = item.title,
|
||||||
|
childCountTag = child_count_tag
|
||||||
)
|
)
|
||||||
.trim();
|
|
||||||
tmpl.replace("{id}", &format!("{}", item.id))
|
|
||||||
.replace("{parent_id}", &item.parent_id.unwrap_or(0).to_string())
|
|
||||||
.replace("{title}", &item.title)
|
|
||||||
.replace(
|
|
||||||
"{childCountTag}",
|
|
||||||
&match item.children_count {
|
|
||||||
Some(cc) => format!("childCount=\"{}\"", cc),
|
|
||||||
None => String::new(),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match item_or_container {
|
match item_or_container {
|
||||||
|
|
@ -67,27 +63,20 @@ pub fn render_content_directory_browse(items: impl IntoIterator<Item = ItemOrCon
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Envelope<'a> {
|
struct Envelope<'a> {
|
||||||
result: &'a str,
|
items: &'a str,
|
||||||
number_returned: usize,
|
number_returned: usize,
|
||||||
total_matches: usize,
|
total_matches: usize,
|
||||||
update_id: u64,
|
update_id: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_content_directory_envelope(envelope: &Envelope<'_>) -> String {
|
fn render_response(envelope: &Envelope<'_>) -> String {
|
||||||
let tmpl =
|
format!(
|
||||||
include_str!("resources/templates/content_directory_control_browse_envelope.tmpl.xml")
|
include_str!("resources/templates/content_directory/control/browse/response.tmpl.xml"),
|
||||||
.trim();
|
items = envelope.items,
|
||||||
tmpl.replace("{result}", envelope.result)
|
number_returned = envelope.number_returned,
|
||||||
.replace("{number_returned}", &envelope.number_returned.to_string())
|
total_matches = envelope.total_matches,
|
||||||
.replace("{total_matches}", &envelope.total_matches.to_string())
|
update_id = envelope.update_id
|
||||||
.replace("{update_id}", &envelope.update_id.to_string())
|
)
|
||||||
}
|
|
||||||
|
|
||||||
fn render_content_directory_browse_result(items: &str) -> String {
|
|
||||||
let tmpl =
|
|
||||||
include_str!("resources/templates/content_directory_control_browse_result.tmpl.xml")
|
|
||||||
.trim();
|
|
||||||
tmpl.replace("{items}", items)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let all_items = items
|
let all_items = items
|
||||||
|
|
@ -97,16 +86,14 @@ pub fn render_content_directory_browse(items: impl IntoIterator<Item = ItemOrCon
|
||||||
let total = all_items.len();
|
let total = all_items.len();
|
||||||
let all_items = all_items.join("");
|
let all_items = all_items.join("");
|
||||||
|
|
||||||
let result = render_content_directory_browse_result(&all_items);
|
|
||||||
|
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
let update_id = SystemTime::now()
|
let update_id = SystemTime::now()
|
||||||
.duration_since(UNIX_EPOCH)
|
.duration_since(UNIX_EPOCH)
|
||||||
.map(|d| d.as_secs())
|
.map(|d| d.as_secs())
|
||||||
.unwrap_or(0);
|
.unwrap_or(0);
|
||||||
|
|
||||||
render_content_directory_envelope(&Envelope {
|
render_response(&Envelope {
|
||||||
result: &result,
|
items: &all_items,
|
||||||
number_returned: total,
|
number_returned: total,
|
||||||
total_matches: total,
|
total_matches: total,
|
||||||
update_id,
|
update_id,
|
||||||
|
|
@ -114,11 +101,19 @@ pub fn render_content_directory_browse(items: impl IntoIterator<Item = ItemOrCon
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_notify_subscription_system_update_id(update_id: u64) -> String {
|
pub fn render_notify_subscription_system_update_id(update_id: u64) -> String {
|
||||||
include_str!("resources/templates/notify_subscription.tmpl.xml")
|
format!(
|
||||||
.replace("{system_update_id}", &update_id.to_string())
|
include_str!(
|
||||||
|
"resources/templates/content_directory/subscriptions/system_update_id.tmpl.xml"
|
||||||
|
),
|
||||||
|
system_update_id = update_id
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_content_directory_control_get_system_update_id(update_id: u64) -> String {
|
pub fn render_content_directory_control_get_system_update_id(update_id: u64) -> String {
|
||||||
include_str!("resources/templates/content_directory_control_get_system_update_id.tmpl.xml")
|
format!(
|
||||||
.replace("{id}", &update_id.to_string())
|
include_str!(
|
||||||
|
"resources/templates/content_directory/control/get_system_update_id/response.tmpl.xml"
|
||||||
|
),
|
||||||
|
id = update_id
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue