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.
208 lines
6.4 KiB
Rust
208 lines
6.4 KiB
Rust
// This file was originally based on
|
|
// <https://github.com/timothee-haudebourg/json-ld/blob/0.12.1/core/src/loader/reqwest/content_type.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 mime::Mime;
|
|
use reqwest::header::HeaderValue;
|
|
use std::str::FromStr;
|
|
|
|
use crate::util::header::{Item, ParseHeader, ParseOptions};
|
|
|
|
/// Helper structure for parsing the `Content-Type` header for JSON-LD.
|
|
pub struct ContentType {
|
|
mime: Mime,
|
|
profile: Option<String>,
|
|
}
|
|
|
|
impl ContentType {
|
|
pub fn from_header(value: &HeaderValue) -> Option<ContentType> {
|
|
let item = Item::parse_from_header(value, ParseOptions::rfc8941()).ok()?;
|
|
let mime = Mime::from_str(item.as_token()?).ok()?;
|
|
let profile = item
|
|
.param("profile")
|
|
.and_then(|profile| profile.as_string_or_token());
|
|
Some(ContentType { mime, profile })
|
|
}
|
|
|
|
pub fn is_json_ld(&self) -> bool {
|
|
[
|
|
"application/activity+json",
|
|
"application/ld+json",
|
|
"application/json",
|
|
]
|
|
.contains(&self.mime.as_ref())
|
|
}
|
|
|
|
pub fn is_proper_json_ld(&self) -> bool {
|
|
["application/activity+json", "application/ld+json"].contains(&self.mime.as_ref())
|
|
}
|
|
|
|
pub fn mime(&self) -> &Mime {
|
|
&self.mime
|
|
}
|
|
|
|
pub fn into_mime(self) -> Mime {
|
|
self.mime
|
|
}
|
|
|
|
pub fn profile(&self) -> Option<&str> {
|
|
self.profile.as_deref()
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn parse_content_type_1() {
|
|
let content_type = ContentType::from_header(
|
|
&HeaderValue::from_str(
|
|
"application/ld+json;profile=http://www.w3.org/ns/json-ld#expanded",
|
|
)
|
|
.unwrap(),
|
|
)
|
|
.unwrap();
|
|
assert_eq!(*content_type.mime(), "application/ld+json");
|
|
assert_eq!(
|
|
content_type.profile(),
|
|
Some("http://www.w3.org/ns/json-ld#expanded")
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn parse_content_type_2() {
|
|
let content_type = ContentType::from_header(
|
|
&HeaderValue::from_str(
|
|
"application/ld+json; profile=http://www.w3.org/ns/json-ld#expanded",
|
|
)
|
|
.unwrap(),
|
|
)
|
|
.unwrap();
|
|
assert_eq!(*content_type.mime(), "application/ld+json");
|
|
assert_eq!(
|
|
content_type.profile(),
|
|
Some("http://www.w3.org/ns/json-ld#expanded")
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn parse_content_type_3() {
|
|
let content_type = ContentType::from_header(
|
|
&HeaderValue::from_str(
|
|
"application/ld+json; profile=http://www.w3.org/ns/json-ld#expanded; q=1",
|
|
)
|
|
.unwrap(),
|
|
)
|
|
.unwrap();
|
|
assert_eq!(*content_type.mime(), "application/ld+json");
|
|
assert_eq!(
|
|
content_type.profile(),
|
|
Some("http://www.w3.org/ns/json-ld#expanded")
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn parse_content_type_4() {
|
|
let content_type = ContentType::from_header(
|
|
&HeaderValue::from_str(
|
|
"application/ld+json; profile=\"http://www.w3.org/ns/json-ld#expanded\"; q=1",
|
|
)
|
|
.unwrap(),
|
|
)
|
|
.unwrap();
|
|
assert_eq!(*content_type.mime(), "application/ld+json");
|
|
assert_eq!(
|
|
content_type.profile(),
|
|
Some("http://www.w3.org/ns/json-ld#expanded")
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn parse_content_type_5() {
|
|
let content_type = ContentType::from_header(
|
|
&HeaderValue::from_str(
|
|
"application/ld+json; profile=\"http://www.w3.org/ns/json-ld#expanded\"",
|
|
)
|
|
.unwrap(),
|
|
)
|
|
.unwrap();
|
|
assert_eq!(*content_type.mime(), "application/ld+json");
|
|
assert_eq!(
|
|
content_type.profile(),
|
|
Some("http://www.w3.org/ns/json-ld#expanded")
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn parse_content_type_6() {
|
|
let content_type = ContentType::from_header(
|
|
&HeaderValue::from_str(
|
|
"application/ld+json;profile=\"http://www.w3.org/ns/json-ld#expanded\"; q=1",
|
|
)
|
|
.unwrap(),
|
|
)
|
|
.unwrap();
|
|
assert_eq!(*content_type.mime(), "application/ld+json");
|
|
assert_eq!(
|
|
content_type.profile(),
|
|
Some("http://www.w3.org/ns/json-ld#expanded")
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn parse_content_type_7() {
|
|
let content_type = ContentType::from_header(&HeaderValue::from_str("application/ld+json; profile=\"http://www.w3.org/ns/json-ld#flattened http://www.w3.org/ns/json-ld#compacted\"; q=1").unwrap()).unwrap();
|
|
assert_eq!(*content_type.mime(), "application/ld+json");
|
|
assert_eq!(
|
|
content_type.profile(),
|
|
Some("http://www.w3.org/ns/json-ld#flattened http://www.w3.org/ns/json-ld#compacted")
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn parse_content_type_8() {
|
|
let content_type =
|
|
ContentType::from_header(&HeaderValue::from_str("application/ld+json").unwrap())
|
|
.unwrap();
|
|
assert_eq!(*content_type.mime(), "application/ld+json");
|
|
}
|
|
|
|
#[test]
|
|
fn is_proper_json_ld() {
|
|
let content_type =
|
|
ContentType::from_header(&HeaderValue::from_str("application/ld+json").unwrap())
|
|
.unwrap();
|
|
assert!(content_type.is_json_ld());
|
|
assert!(content_type.is_proper_json_ld());
|
|
|
|
let content_type =
|
|
ContentType::from_header(&HeaderValue::from_str("application/activity+json").unwrap())
|
|
.unwrap();
|
|
assert!(content_type.is_json_ld());
|
|
assert!(content_type.is_proper_json_ld());
|
|
}
|
|
|
|
#[test]
|
|
fn is_json_ld() {
|
|
let content_type =
|
|
ContentType::from_header(&HeaderValue::from_str("application/json").unwrap()).unwrap();
|
|
assert!(content_type.is_json_ld());
|
|
assert!(!content_type.is_proper_json_ld());
|
|
}
|
|
|
|
#[test]
|
|
fn is_not_json_ld() {
|
|
let content_type =
|
|
ContentType::from_header(&HeaderValue::from_str("application/xml").unwrap()).unwrap();
|
|
assert!(!content_type.is_json_ld());
|
|
assert!(!content_type.is_proper_json_ld());
|
|
}
|
|
}
|