Skip to content

Commit d74d92d

Browse files
committed
fix(core): don't take an href when making links absolute
1 parent f19d44b commit d74d92d

File tree

6 files changed

+63
-28
lines changed

6 files changed

+63
-28
lines changed

api/src/collections.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use serde::{Deserialize, Serialize};
22
use serde_json::{Map, Value};
3-
use stac::{Collection, Link, Links};
3+
use stac::{Collection, Href, Link, Links};
44

55
/// Object containing an array of collections and an array of links.
66
#[derive(Debug, Serialize, Deserialize)]
@@ -14,6 +14,9 @@ pub struct Collections {
1414
/// Additional fields.
1515
#[serde(flatten)]
1616
pub additional_fields: Map<String, Value>,
17+
18+
#[serde(skip)]
19+
href: Option<String>,
1720
}
1821

1922
impl From<Vec<Collection>> for Collections {
@@ -22,10 +25,23 @@ impl From<Vec<Collection>> for Collections {
2225
collections,
2326
links: Vec::new(),
2427
additional_fields: Map::new(),
28+
href: None,
2529
}
2630
}
2731
}
2832

33+
impl Href for Collections {
34+
fn href(&self) -> Option<&str> {
35+
self.href.as_deref()
36+
}
37+
fn set_href(&mut self, href: impl ToString) {
38+
self.href = Some(href.to_string());
39+
}
40+
fn clear_href(&mut self) {
41+
self.href = None;
42+
}
43+
}
44+
2945
impl Links for Collections {
3046
fn links(&self) -> &[Link] {
3147
&self.links

api/src/item_collection.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{Item, Result};
22
use serde::{Deserialize, Serialize};
33
use serde_json::{Map, Value};
4-
use stac::{Link, Links};
4+
use stac::{Href, Link, Links};
55

66
const ITEM_COLLECTION_TYPE: &str = "FeatureCollection";
77

@@ -71,6 +71,9 @@ pub struct ItemCollection {
7171
/// pagination information (tokens) to later be turned into links.
7272
#[serde(skip)]
7373
pub last: Option<Map<String, Value>>,
74+
75+
#[serde(skip)]
76+
href: Option<String>,
7477
}
7578

7679
/// The search-related metadata for the [ItemCollection].
@@ -118,10 +121,23 @@ impl ItemCollection {
118121
prev: None,
119122
first: None,
120123
last: None,
124+
href: None,
121125
})
122126
}
123127
}
124128

129+
impl Href for ItemCollection {
130+
fn set_href(&mut self, href: impl ToString) {
131+
self.href = Some(href.to_string());
132+
}
133+
fn clear_href(&mut self) {
134+
self.href = None;
135+
}
136+
fn href(&self) -> Option<&str> {
137+
self.href.as_deref()
138+
}
139+
}
140+
125141
impl Links for ItemCollection {
126142
fn links(&self) -> &[Link] {
127143
&self.links
@@ -145,6 +161,7 @@ impl Default for ItemCollection {
145161
prev: None,
146162
first: None,
147163
last: None,
164+
href: None,
148165
}
149166
}
150167
}

cli/src/args/serve.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::{Input, Run};
22
use crate::{Error, Result, Value};
3-
use stac::{Collection, Href, Item, Links};
3+
use stac::{Collection, Item, Links};
44
use stac_server::{Api, Backend as _, MemoryBackend};
55
use std::collections::{HashMap, HashSet};
66
use tokio::{net::TcpListener, sync::mpsc::Sender, task::JoinSet};
@@ -94,8 +94,7 @@ impl Run for Args {
9494
}
9595
Value::Collection(mut collection) => {
9696
if self.load_collection_items {
97-
let href = collection.href().expect("we just read it").to_string();
98-
collection.make_relative_links_absolute(href)?;
97+
collection.make_relative_links_absolute()?;
9998
for link in collection.iter_item_links() {
10099
let href = link.href.to_string();
101100
let input = input.with_href(href);

core/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
2828

2929
- `Error::ReqwestNotEnabled` and `Error::GdalNotEnabled` ([#396](https://github.com/stac-utils/stac-rs/pull/382))
3030
- `Asset::extensions` ([#405](https://github.com/stac-utils/stac-rs/pull/405))
31+
- `href` argument to `Links::make_relative_links_absolute` ([#407](https://github.com/stac-utils/stac-rs/pull/407))
3132

3233
## [0.9.0] - 2024-09-05
3334

core/src/error.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ pub enum Error {
8383
#[error("no items")]
8484
NoItems,
8585

86+
/// There is not an href, when an href is required.
87+
#[error("no href")]
88+
NoHref,
89+
8690
/// This value is not an item.
8791
#[error("value is not an item")]
8892
NotAnItem(Value),

core/src/link.rs

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Links.
22
3-
use crate::{mime::APPLICATION_GEOJSON, Error, Result};
3+
use crate::{mime::APPLICATION_GEOJSON, Error, Href, Result};
44
use mime::APPLICATION_JSON;
55
use serde::{Deserialize, Serialize};
66
use serde_json::{Map, Value};
@@ -88,7 +88,7 @@ pub struct Link {
8888
}
8989

9090
/// Implemented by any object that has links.
91-
pub trait Links {
91+
pub trait Links: Href {
9292
/// Returns a reference to this object's links.
9393
///
9494
/// # Examples
@@ -217,7 +217,7 @@ pub trait Links {
217217
Box::new(self.links().iter().filter(|link| link.is_item()))
218218
}
219219

220-
/// Makes all relative links absolute with respect to an href.
220+
/// Makes all relative links absolute with respect to this object's href.
221221
///
222222
/// # Examples
223223
///
@@ -226,15 +226,19 @@ pub trait Links {
226226
///
227227
/// let mut catalog: stac::Catalog = stac::read("examples/catalog.json").unwrap();
228228
/// assert!(!catalog.root_link().unwrap().is_absolute());
229-
/// catalog.make_relative_links_absolute("examples/catalog.json").unwrap();
229+
/// catalog.make_relative_links_absolute().unwrap();
230230
/// assert!(catalog.root_link().unwrap().is_absolute());
231231
/// ```
232-
fn make_relative_links_absolute(&mut self, href: impl ToString) -> Result<()> {
233-
let href = make_absolute(href.to_string(), None)?;
234-
for link in self.links_mut() {
235-
link.href = make_absolute(std::mem::take(&mut link.href), Some(&href))?;
232+
fn make_relative_links_absolute(&mut self) -> Result<()> {
233+
if let Some(href) = self.href() {
234+
let href = make_absolute(href.to_string(), None)?;
235+
for link in self.links_mut() {
236+
link.href = make_absolute(std::mem::take(&mut link.href), Some(&href))?;
237+
}
238+
Ok(())
239+
} else {
240+
Err(Error::NoHref)
236241
}
237-
Ok(())
238242
}
239243

240244
/// Makes all absolute links relative with respect to an href.
@@ -248,7 +252,7 @@ pub trait Links {
248252
///
249253
/// let mut catalog: stac::Catalog = stac::read("examples/catalog.json").unwrap();
250254
/// assert!(!catalog.root_link().unwrap().is_absolute());
251-
/// catalog.make_relative_links_absolute("examples/catalog.json").unwrap();
255+
/// catalog.make_relative_links_absolute().unwrap();
252256
/// assert!(catalog.root_link().unwrap().is_absolute());
253257
/// catalog.make_absolute_links_relative("examples/catalog.json").unwrap();
254258
/// assert!(catalog.root_link().unwrap().is_relative());
@@ -817,7 +821,7 @@ mod tests {
817821
}
818822

819823
mod links {
820-
use crate::{Catalog, Item, Link, Links};
824+
use crate::{Catalog, Href, Item, Link, Links};
821825

822826
#[test]
823827
fn link() {
@@ -846,9 +850,7 @@ mod tests {
846850
#[test]
847851
fn make_relative_links_absolute_path() {
848852
let mut catalog: Catalog = crate::read("examples/catalog.json").unwrap();
849-
catalog
850-
.make_relative_links_absolute("examples/catalog.json")
851-
.unwrap();
853+
catalog.make_relative_links_absolute().unwrap();
852854
for link in catalog.links() {
853855
assert!(link.is_absolute());
854856
}
@@ -857,9 +859,8 @@ mod tests {
857859
#[test]
858860
fn make_relative_links_absolute_url() {
859861
let mut catalog: Catalog = crate::read("examples/catalog.json").unwrap();
860-
catalog
861-
.make_relative_links_absolute("http://stac-rs.test/catalog.json")
862-
.unwrap();
862+
catalog.set_href("http://stac-rs.test/catalog.json");
863+
catalog.make_relative_links_absolute().unwrap();
863864
for link in catalog.links() {
864865
assert!(link.is_absolute());
865866
}
@@ -872,9 +873,7 @@ mod tests {
872873
#[test]
873874
fn make_absolute_links_relative_path() {
874875
let mut catalog: Catalog = crate::read("examples/catalog.json").unwrap();
875-
catalog
876-
.make_relative_links_absolute("examples/catalog.json")
877-
.unwrap();
876+
catalog.make_relative_links_absolute().unwrap();
878877
catalog.make_absolute_links_relative("examples/").unwrap();
879878
for link in catalog.links() {
880879
if !link.is_self() {
@@ -886,9 +885,8 @@ mod tests {
886885
#[test]
887886
fn make_absolute_links_relative_url() {
888887
let mut catalog: Catalog = crate::read("examples/catalog.json").unwrap();
889-
catalog
890-
.make_relative_links_absolute("http://stac-rs.test/catalog.json")
891-
.unwrap();
888+
catalog.set_href("http://stac-rs.test/catalog.json");
889+
catalog.make_relative_links_absolute().unwrap();
892890
catalog
893891
.make_absolute_links_relative("http://stac-rs.test/")
894892
.unwrap();

0 commit comments

Comments
 (0)