ogcapi-types 0.1.0

Types as defined by various OGC API Standards.
Documentation
use url::Url;

use super::{link_rel::SELF, Link};

#[doc(hidden)]
pub type Links = Vec<Link>;

#[doc(hidden)]
pub trait Linked {
    fn get_base_url(&mut self) -> Option<Url>;

    fn resolve_relative_links(&mut self);

    fn insert_or_update(&mut self, other: &[Link]);
}

impl Linked for Links {
    fn get_base_url(&mut self) -> Option<Url> {
        self.iter()
            .find(|l| l.rel == SELF)
            .and_then(|l| l.href.parse().ok())
    }

    fn resolve_relative_links(&mut self) {
        if let Some(base) = self.get_base_url() {
            for link in self.iter_mut() {
                if link.href.starts_with("http") || link.href.starts_with('/') {
                    continue;
                }

                match base.join(&link.href) {
                    Ok(url) => link.href = url.to_string(),
                    Err(_) => {
                        eprintln!(
                            "Unable to resolve link `{}` with base `{}`",
                            link.href, base
                        )
                    }
                }
            }
        }
    }

    fn insert_or_update(&mut self, others: &[Link]) {
        for link in others {
            self.iter_mut()
                .find(|l| l.rel == link.rel)
                .map(|l| l.href = link.href.to_owned())
                .unwrap_or_else(|| self.push(link.to_owned()));
        }
    }
}