diff --git a/src/subcommand/server.rs b/src/subcommand/server.rs index ea1bb463c1..96c10679b0 100644 --- a/src/subcommand/server.rs +++ b/src/subcommand/server.rs @@ -4,7 +4,8 @@ use { self::{ deserialize_ordinal_from_str::DeserializeOrdinalFromStr, templates::{ - block::BlockHtml, ordinal::OrdinalHtml, root::RootHtml, transaction::TransactionHtml, Content, + block::BlockHtml, ordinal::OrdinalHtml, output::OutputHtml, root::RootHtml, + transaction::TransactionHtml, Content, }, tls_acceptor::TlsAcceptor, }, @@ -175,22 +176,12 @@ impl Server { extract::Path(outpoint): extract::Path, ) -> impl IntoResponse { match index.list(outpoint) { - Ok(Some(ranges)) => ( - StatusCode::OK, - Html(format!( - "", - ranges - .iter() - .map(|(start, end)| format!( - "
  • [{start},{end})
  • " - )) - .collect::() - )), - ), + Ok(Some(ranges)) => OutputHtml { outpoint, ranges }.page().into_response(), Ok(None) => ( StatusCode::NOT_FOUND, Html("Output unknown, invalid, or spent.".to_string()), - ), + ) + .into_response(), Err(err) => { eprintln!("Error serving request for output: {err}"); ( @@ -202,6 +193,7 @@ impl Server { .to_string(), ), ) + .into_response() } } } diff --git a/src/subcommand/server/templates.rs b/src/subcommand/server/templates.rs index 2fb3673604..3163726964 100644 --- a/src/subcommand/server/templates.rs +++ b/src/subcommand/server/templates.rs @@ -2,6 +2,7 @@ use {super::*, boilerplate::Display}; pub(crate) mod block; pub(crate) mod ordinal; +pub(crate) mod output; pub(crate) mod root; pub(crate) mod transaction; diff --git a/src/subcommand/server/templates/output.rs b/src/subcommand/server/templates/output.rs new file mode 100644 index 0000000000..a690088a74 --- /dev/null +++ b/src/subcommand/server/templates/output.rs @@ -0,0 +1,46 @@ +use super::*; + +#[derive(Display)] +pub(crate) struct OutputHtml { + pub(crate) outpoint: OutPoint, + pub(crate) ranges: Vec<(u64, u64)>, +} + +impl Content for OutputHtml { + fn title(&self) -> String { + format!("Output {}", self.outpoint) + } + + fn page(self) -> PageHtml { + PageHtml { + content: Box::new(self), + } + } +} + +#[cfg(test)] +mod tests { + use {super::*, pretty_assertions::assert_eq, unindent::Unindent}; + + #[test] + fn output_html() { + assert_eq!( + OutputHtml { + outpoint: "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b:0" + .parse() + .unwrap(), + ranges: vec![(0, 1), (1, 2)] + } + .to_string(), + " +

    Output 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b:0

    +

    Ordinal Ranges

    + + " + .unindent() + ); + } +} diff --git a/templates/output.html b/templates/output.html new file mode 100644 index 0000000000..ede2e426ea --- /dev/null +++ b/templates/output.html @@ -0,0 +1,7 @@ +

    Output {{self.outpoint}}

    +

    Ordinal Ranges

    + diff --git a/tests/server.rs b/tests/server.rs index 085a020cb2..d5354f8537 100644 --- a/tests/server.rs +++ b/tests/server.rs @@ -105,7 +105,7 @@ fn invalid_outpoint_hash_returns_400() { } #[test] -fn outpoint_returns_ordinal_ranges() { +fn output() { let mut state = State::new(); state.blocks(1); @@ -115,7 +115,11 @@ fn outpoint_returns_ordinal_ranges() { state.request_regex( "output/4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b:0", 200, - ".*.*", + ".*Output 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b:0.*

    Output 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b:0

    +

    Ordinal Ranges

    +.*", ); }