Skip to content

Commit

Permalink
fix(core): don't take an href when making links absolute
Browse files Browse the repository at this point in the history
  • Loading branch information
gadomski committed Sep 19, 2024
1 parent 8dcd257 commit dcc13ef
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 27 deletions.
18 changes: 17 additions & 1 deletion api/src/collections.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
use stac::{Collection, Link, Links};
use stac::{Collection, Href, Link, Links};

/// Object containing an array of collections and an array of links.
#[derive(Debug, Serialize, Deserialize)]
Expand All @@ -14,6 +14,9 @@ pub struct Collections {
/// Additional fields.
#[serde(flatten)]
pub additional_fields: Map<String, Value>,

#[serde(skip)]
href: Option<String>,
}

impl From<Vec<Collection>> for Collections {
Expand All @@ -22,10 +25,23 @@ impl From<Vec<Collection>> for Collections {
collections,
links: Vec::new(),
additional_fields: Map::new(),
href: None,
}
}
}

impl Href for Collections {
fn href(&self) -> Option<&str> {
self.href.as_deref()
}
fn set_href(&mut self, href: impl ToString) {
self.href = Some(href.to_string());
}
fn clear_href(&mut self) {
self.href = None;
}
}

impl Links for Collections {
fn links(&self) -> &[Link] {
&self.links
Expand Down
19 changes: 18 additions & 1 deletion api/src/item_collection.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{Item, Result};
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
use stac::{Link, Links};
use stac::{Href, Link, Links};

const ITEM_COLLECTION_TYPE: &str = "FeatureCollection";

Expand Down Expand Up @@ -71,6 +71,9 @@ pub struct ItemCollection {
/// pagination information (tokens) to later be turned into links.
#[serde(skip)]
pub last: Option<Map<String, Value>>,

#[serde(skip)]
href: Option<String>,
}

/// The search-related metadata for the [ItemCollection].
Expand Down Expand Up @@ -118,10 +121,23 @@ impl ItemCollection {
prev: None,
first: None,
last: None,
href: None,
})
}
}

impl Href for ItemCollection {
fn set_href(&mut self, href: impl ToString) {
self.href = Some(href.to_string());
}
fn clear_href(&mut self) {
self.href = None;
}
fn href(&self) -> Option<&str> {
self.href.as_deref()
}
}

impl Links for ItemCollection {
fn links(&self) -> &[Link] {
&self.links
Expand All @@ -145,6 +161,7 @@ impl Default for ItemCollection {
prev: None,
first: None,
last: None,
href: None,
}
}
}
Expand Down
5 changes: 2 additions & 3 deletions cli/src/args/serve.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::{Input, Run};
use crate::{Error, Result, Value};
use stac::{Collection, Href, Item, Links};
use stac::{Collection, Item, Links};
use stac_server::{Api, Backend as _, MemoryBackend};
use std::collections::{HashMap, HashSet};
use tokio::{net::TcpListener, sync::mpsc::Sender, task::JoinSet};
Expand Down Expand Up @@ -94,8 +94,7 @@ impl Run for Args {
}
Value::Collection(mut collection) => {
if self.load_collection_items {
let href = collection.href().expect("we just read it").to_string();
collection.make_relative_links_absolute(href)?;
collection.make_relative_links_absolute()?;
for link in collection.iter_item_links() {
let href = link.href.to_string();
let input = input.with_href(href);
Expand Down
4 changes: 4 additions & 0 deletions core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ pub enum Error {
#[error("no items")]
NoItems,

/// There is not an href, when an href is required.
#[error("no href")]
NoHref,

/// This value is not an item.
#[error("value is not an item")]
NotAnItem(Value),
Expand Down
42 changes: 20 additions & 22 deletions core/src/link.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Links.

use crate::{mime::APPLICATION_GEOJSON, Error, Result};
use crate::{mime::APPLICATION_GEOJSON, Error, Href, Result};
use mime::APPLICATION_JSON;
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
Expand Down Expand Up @@ -88,7 +88,7 @@ pub struct Link {
}

/// Implemented by any object that has links.
pub trait Links {
pub trait Links: Href {
/// Returns a reference to this object's links.
///
/// # Examples
Expand Down Expand Up @@ -217,7 +217,7 @@ pub trait Links {
Box::new(self.links().iter().filter(|link| link.is_item()))
}

/// Makes all relative links absolute with respect to an href.
/// Makes all relative links absolute with respect to this object's href.
///
/// # Examples
///
Expand All @@ -226,15 +226,19 @@ pub trait Links {
///
/// let mut catalog: stac::Catalog = stac::read("examples/catalog.json").unwrap();
/// assert!(!catalog.root_link().unwrap().is_absolute());
/// catalog.make_relative_links_absolute("examples/catalog.json").unwrap();
/// catalog.make_relative_links_absolute().unwrap();
/// assert!(catalog.root_link().unwrap().is_absolute());
/// ```
fn make_relative_links_absolute(&mut self, href: impl ToString) -> Result<()> {
let href = make_absolute(href.to_string(), None)?;
for link in self.links_mut() {
link.href = make_absolute(std::mem::take(&mut link.href), Some(&href))?;
fn make_relative_links_absolute(&mut self) -> Result<()> {
if let Some(href) = self.href() {
let href = make_absolute(href.to_string(), None)?;
for link in self.links_mut() {
link.href = make_absolute(std::mem::take(&mut link.href), Some(&href))?;
}
Ok(())
} else {
Err(Error::NoHref)
}
Ok(())
}

/// Makes all absolute links relative with respect to an href.
Expand Down Expand Up @@ -817,7 +821,7 @@ mod tests {
}

mod links {
use crate::{Catalog, Item, Link, Links};
use crate::{Catalog, Href, Item, Link, Links};

#[test]
fn link() {
Expand Down Expand Up @@ -846,9 +850,7 @@ mod tests {
#[test]
fn make_relative_links_absolute_path() {
let mut catalog: Catalog = crate::read("examples/catalog.json").unwrap();
catalog
.make_relative_links_absolute("examples/catalog.json")
.unwrap();
catalog.make_relative_links_absolute().unwrap();
for link in catalog.links() {
assert!(link.is_absolute());
}
Expand All @@ -857,9 +859,8 @@ mod tests {
#[test]
fn make_relative_links_absolute_url() {
let mut catalog: Catalog = crate::read("examples/catalog.json").unwrap();
catalog
.make_relative_links_absolute("http://stac-rs.test/catalog.json")
.unwrap();
catalog.set_href("http://stac-rs.test/catalog.json");
catalog.make_relative_links_absolute().unwrap();
for link in catalog.links() {
assert!(link.is_absolute());
}
Expand All @@ -872,9 +873,7 @@ mod tests {
#[test]
fn make_absolute_links_relative_path() {
let mut catalog: Catalog = crate::read("examples/catalog.json").unwrap();
catalog
.make_relative_links_absolute("examples/catalog.json")
.unwrap();
catalog.make_relative_links_absolute().unwrap();
catalog.make_absolute_links_relative("examples/").unwrap();
for link in catalog.links() {
if !link.is_self() {
Expand All @@ -886,9 +885,8 @@ mod tests {
#[test]
fn make_absolute_links_relative_url() {
let mut catalog: Catalog = crate::read("examples/catalog.json").unwrap();
catalog
.make_relative_links_absolute("http://stac-rs.test/catalog.json")
.unwrap();
catalog.set_href("http://stac-rs.test/catalog.json");
catalog.make_relative_links_absolute().unwrap();
catalog
.make_absolute_links_relative("http://stac-rs.test/")
.unwrap();
Expand Down

0 comments on commit dcc13ef

Please sign in to comment.