diff --git a/src/index.rs b/src/index.rs index c077a8ba4c..837a27d129 100644 --- a/src/index.rs +++ b/src/index.rs @@ -251,7 +251,7 @@ impl Index { let height_to_hash = rtx.0.open_table(HEIGHT_TO_HASH)?; let mut cursor = height_to_hash - .range(height.saturating_sub(take)..=height)? + .range(height.saturating_sub(take.saturating_sub(1))..=height)? .rev(); while let Some(next) = cursor.next() { diff --git a/src/subcommand/server.rs b/src/subcommand/server.rs index 96c10679b0..786dfb6ec3 100644 --- a/src/subcommand/server.rs +++ b/src/subcommand/server.rs @@ -4,7 +4,7 @@ use { self::{ deserialize_ordinal_from_str::DeserializeOrdinalFromStr, templates::{ - block::BlockHtml, ordinal::OrdinalHtml, output::OutputHtml, root::RootHtml, + block::BlockHtml, ordinal::OrdinalHtml, output::OutputHtml, range::RangeHtml, root::RootHtml, transaction::TransactionHtml, Content, }, tls_acceptor::TlsAcceptor, @@ -16,6 +16,7 @@ use { AcmeConfig, }, serde::{de, Deserializer}, + std::cmp::Ordering, tokio_stream::StreamExt, }; @@ -203,21 +204,15 @@ impl Server { (DeserializeOrdinalFromStr, DeserializeOrdinalFromStr), >, ) -> impl IntoResponse { - if start == end { - return (StatusCode::BAD_REQUEST, Html("Empty Range".to_string())); - } - - if start > end { - return ( + match start.cmp(&end) { + Ordering::Equal => (StatusCode::BAD_REQUEST, Html("Empty Range".to_string())).into_response(), + Ordering::Greater => ( StatusCode::BAD_REQUEST, Html("Range Start Greater Than Range End".to_string()), - ); + ) + .into_response(), + Ordering::Less => RangeHtml { start, end }.page().into_response(), } - - ( - StatusCode::OK, - Html(format!("first")), - ) } async fn root(index: extract::Extension>) -> impl IntoResponse { diff --git a/src/subcommand/server/templates.rs b/src/subcommand/server/templates.rs index 3163726964..a5f76222b6 100644 --- a/src/subcommand/server/templates.rs +++ b/src/subcommand/server/templates.rs @@ -3,6 +3,7 @@ use {super::*, boilerplate::Display}; pub(crate) mod block; pub(crate) mod ordinal; pub(crate) mod output; +pub(crate) mod range; pub(crate) mod root; pub(crate) mod transaction; diff --git a/src/subcommand/server/templates/range.rs b/src/subcommand/server/templates/range.rs new file mode 100644 index 0000000000..96a4715435 --- /dev/null +++ b/src/subcommand/server/templates/range.rs @@ -0,0 +1,62 @@ +use super::*; + +#[derive(Display)] +pub(crate) struct RangeHtml { + pub(crate) start: Ordinal, + pub(crate) end: Ordinal, +} + +impl Content for RangeHtml { + fn title(&self) -> String { + format!("Ordinal range [{},{})", self.start, self.end) + } + + fn page(self) -> PageHtml { + PageHtml { + content: Box::new(self), + } + } +} + +#[cfg(test)] +mod tests { + use {super::*, pretty_assertions::assert_eq, unindent::Unindent}; + + #[test] + fn ordinal_html() { + assert_eq!( + RangeHtml { + start: Ordinal(0), + end: Ordinal(1), + } + .to_string(), + " +

Ordinal range [0,1)

+
+
size
1
+
first
0
+
+ " + .unindent() + ); + } + + #[test] + fn bugfix_broken_link() { + assert_eq!( + RangeHtml { + start: Ordinal(1), + end: Ordinal(10), + } + .to_string(), + " +

Ordinal range [1,10)

+
+
size
9
+
first
1
+
+ " + .unindent() + ); + } +} diff --git a/templates/range.html b/templates/range.html new file mode 100644 index 0000000000..ada1a58ca6 --- /dev/null +++ b/templates/range.html @@ -0,0 +1,5 @@ +

Ordinal range [{{self.start}},{{self.end}})

+
+
size
{{self.end.n() - self.start.n()}}
+
first
{{self.start.n()}}
+
diff --git a/tests/server.rs b/tests/server.rs index d5354f8537..9b4089f8ab 100644 --- a/tests/server.rs +++ b/tests/server.rs @@ -62,8 +62,16 @@ fn empty_range_returns_400() { } #[test] -fn range_links_to_first() { - State::new().request("range/0/1", 200, "first"); +fn range() { + State::new().request_regex( + "range/0/1", + 200, + r".*Ordinal range \[0,1\).*

Ordinal range \[0,1\)

+
+
size
1
+
first
0
+
.*", + ); } #[test] @@ -162,7 +170,7 @@ fn root_block_limit() { state.request_regex( "/", 200, - ".*.*" + ".*.*" ); }