You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
107 lines
3.3 KiB
Rust
107 lines
3.3 KiB
Rust
// This file was originally based on
|
|
// <https://github.com/timothee-haudebourg/json-ld/blob/0.12.1/core/src/loader/reqwest/link.rs>.
|
|
//
|
|
// Copyright (C) 2022 Timothée Haudebourg et al.
|
|
// Licensed under either the Apache License, Version 2.0; or the MIT License.
|
|
// See <https://github.com/timothee-haudebourg/json-ld/tree/0.12.1> for details.
|
|
//
|
|
// Heavily modified by anna <owo@fef.moe> to use nyanoblog's own Structured Header
|
|
// parser and accept the `application/activity+json` MIME type as proper JSON-LD.
|
|
|
|
use iref::{IriRef, IriRefBuf};
|
|
use reqwest::header::HeaderValue;
|
|
use std::str::FromStr;
|
|
|
|
use crate::util::header::{Item, ParseHeader, ParseOptions};
|
|
|
|
pub struct Link {
|
|
href: IriRefBuf,
|
|
rel: Option<String>,
|
|
typ: Option<String>,
|
|
}
|
|
|
|
impl Link {
|
|
pub fn from_header(value: &HeaderValue) -> Option<Self> {
|
|
let item = Item::parse_from_header(value, ParseOptions::link_header()).ok()?;
|
|
let href = IriRefBuf::from_str(item.as_url()?).ok()?;
|
|
let rel = item.param("rel").and_then(|rel| rel.as_string());
|
|
let typ = item.param("type").and_then(|typ| typ.as_string());
|
|
Some(Link { href, rel, typ })
|
|
}
|
|
|
|
pub fn href(&self) -> IriRef {
|
|
self.href.as_iri_ref()
|
|
}
|
|
|
|
pub fn rel(&self) -> Option<&str> {
|
|
self.rel.as_deref()
|
|
}
|
|
|
|
pub fn typ(&self) -> Option<&str> {
|
|
self.typ.as_deref()
|
|
}
|
|
|
|
pub fn is_proper_json_ld(&self) -> bool {
|
|
self.typ()
|
|
.filter(|t| ["application/activity+json", "application/ld+json"].contains(t))
|
|
.is_some()
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
fn mklink(header_value: &'static str) -> Option<Link> {
|
|
Link::from_header(&HeaderValue::from_str(header_value).unwrap())
|
|
}
|
|
|
|
#[test]
|
|
fn parse_link_1() {
|
|
let link = mklink(
|
|
"<http://www.example.org/context>; rel=\"context\"; type=\"application/ld+json\"",
|
|
)
|
|
.unwrap();
|
|
assert_eq!(link.href(), "http://www.example.org/context");
|
|
assert_eq!(link.rel(), Some("context"));
|
|
assert_eq!(link.typ(), Some("application/ld+json"))
|
|
}
|
|
|
|
#[test]
|
|
fn parse_link_2() {
|
|
let link = mklink(
|
|
"<http://www.example.org/context>; rel = \"context\" ; type=\"application/ld+json\" ; foo=\"bar\"",
|
|
)
|
|
.unwrap();
|
|
assert_eq!(link.href(), "http://www.example.org/context");
|
|
assert_eq!(link.rel(), Some("context"));
|
|
assert_eq!(link.typ(), Some("application/ld+json"))
|
|
}
|
|
|
|
#[test]
|
|
fn parse_link_3() {
|
|
let link = mklink("<http://www.example.org/context>").unwrap();
|
|
assert_eq!(link.href(), "http://www.example.org/context")
|
|
}
|
|
|
|
#[test]
|
|
fn is_proper_json_ld() {
|
|
let link = mklink(
|
|
"<http://www.example.org/context>; rel=\"context\"; type=\"application/ld+json\"",
|
|
)
|
|
.unwrap();
|
|
assert!(link.is_proper_json_ld());
|
|
|
|
let link = mklink(
|
|
"<http://www.example.org/context>; rel=\"context\"; type=\"application/activity+json\"",
|
|
)
|
|
.unwrap();
|
|
assert!(link.is_proper_json_ld());
|
|
|
|
let link =
|
|
mklink("<http://www.example.org/context>; rel=\"context\"; type=\"application/json\"")
|
|
.unwrap();
|
|
assert!(!link.is_proper_json_ld());
|
|
}
|
|
}
|