fix(apb): actually link href is not guaranteed
This commit is contained in:
parent
c3e319d5a9
commit
2b4fb3bd62
7 changed files with 42 additions and 35 deletions
|
@ -102,7 +102,7 @@ impl<T : super::Base> Node<T> {
|
||||||
pub fn id(&self) -> crate::Field<&str> {
|
pub fn id(&self) -> crate::Field<&str> {
|
||||||
match self {
|
match self {
|
||||||
Node::Empty => Err(crate::FieldErr("id")),
|
Node::Empty => Err(crate::FieldErr("id")),
|
||||||
Node::Link(uri) => Ok(uri.href()),
|
Node::Link(uri) => uri.href(),
|
||||||
Node::Object(obj) => obj.id(),
|
Node::Object(obj) => obj.id(),
|
||||||
Node::Array(arr) => arr.front().map(|x| x.id()).ok_or(crate::FieldErr("id"))?,
|
Node::Array(arr) => arr.front().map(|x| x.id()).ok_or(crate::FieldErr("id"))?,
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ impl<T : super::Base> Node<T> {
|
||||||
pub fn all_ids(&self) -> Vec<String> {
|
pub fn all_ids(&self) -> Vec<String> {
|
||||||
match self {
|
match self {
|
||||||
Node::Empty => vec![],
|
Node::Empty => vec![],
|
||||||
Node::Link(uri) => vec![uri.href().to_string()],
|
Node::Link(uri) => uri.href().map(|x| vec![x.to_string()]).unwrap_or_default(),
|
||||||
Node::Object(x) => x.id().map_or(vec![], |x| vec![x.to_string()]),
|
Node::Object(x) => x.id().map_or(vec![], |x| vec![x.to_string()]),
|
||||||
Node::Array(x) => x.iter().filter_map(|x| Some(x.id().ok()?.to_string())).collect()
|
Node::Array(x) => x.iter().filter_map(|x| Some(x.id().ok()?.to_string())).collect()
|
||||||
}
|
}
|
||||||
|
@ -236,7 +236,7 @@ impl From<Node<serde_json::Value>> for serde_json::Value {
|
||||||
fn from(value: Node<serde_json::Value>) -> Self {
|
fn from(value: Node<serde_json::Value>) -> Self {
|
||||||
match value {
|
match value {
|
||||||
Node::Empty => serde_json::Value::Null,
|
Node::Empty => serde_json::Value::Null,
|
||||||
Node::Link(l) => serde_json::Value::String(l.href().to_string()), // TODO there could be more
|
Node::Link(l) => serde_json::Value::String(l.href().unwrap_or_default().to_string()), // TODO there could be more
|
||||||
Node::Object(o) => *o,
|
Node::Object(o) => *o,
|
||||||
Node::Array(arr) =>
|
Node::Array(arr) =>
|
||||||
serde_json::Value::Array(arr.into_iter().map(|x| x.into()).collect()),
|
serde_json::Value::Array(arr.into_iter().map(|x| x.into()).collect()),
|
||||||
|
|
|
@ -19,7 +19,7 @@ crate::strenum! {
|
||||||
|
|
||||||
pub trait Link : crate::Base {
|
pub trait Link : crate::Base {
|
||||||
fn link_type(&self) -> Field<LinkType> { Err(FieldErr("type")) }
|
fn link_type(&self) -> Field<LinkType> { Err(FieldErr("type")) }
|
||||||
fn href(&self) -> &str;
|
fn href(&self) -> Field<&str>;
|
||||||
fn rel(&self) -> Field<&str> { Err(FieldErr("rel")) }
|
fn rel(&self) -> Field<&str> { Err(FieldErr("rel")) }
|
||||||
fn media_type(&self) -> Field<&str> { Err(FieldErr("mediaType")) } // also in obj
|
fn media_type(&self) -> Field<&str> { Err(FieldErr("mediaType")) } // also in obj
|
||||||
fn name(&self) -> Field<&str> { Err(FieldErr("name")) } // also in obj
|
fn name(&self) -> Field<&str> { Err(FieldErr("name")) } // also in obj
|
||||||
|
@ -31,7 +31,7 @@ pub trait Link : crate::Base {
|
||||||
|
|
||||||
pub trait LinkMut : crate::BaseMut {
|
pub trait LinkMut : crate::BaseMut {
|
||||||
fn set_link_type(self, val: Option<LinkType>) -> Self;
|
fn set_link_type(self, val: Option<LinkType>) -> Self;
|
||||||
fn set_href(self, href: &str) -> Self;
|
fn set_href(self, href: Option<&str>) -> Self;
|
||||||
fn set_rel(self, val: Option<&str>) -> Self;
|
fn set_rel(self, val: Option<&str>) -> Self;
|
||||||
fn set_media_type(self, val: Option<&str>) -> Self; // also in obj
|
fn set_media_type(self, val: Option<&str>) -> Self; // also in obj
|
||||||
fn set_name(self, val: Option<&str>) -> Self; // also in obj
|
fn set_name(self, val: Option<&str>) -> Self; // also in obj
|
||||||
|
@ -42,19 +42,19 @@ pub trait LinkMut : crate::BaseMut {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Link for String {
|
impl Link for String {
|
||||||
fn href(&self) -> &str {
|
fn href(&self) -> Field<&str> {
|
||||||
self
|
Ok(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "unstructured")]
|
#[cfg(feature = "unstructured")]
|
||||||
impl Link for serde_json::Value {
|
impl Link for serde_json::Value {
|
||||||
// TODO this can fail, but it should never do!
|
// TODO this can fail, but it should never do!
|
||||||
fn href(&self) -> &str {
|
fn href(&self) -> Field<&str> {
|
||||||
if self.is_string() {
|
if self.is_string() {
|
||||||
self.as_str().unwrap_or("")
|
self.as_str().ok_or(FieldErr("href"))
|
||||||
} else {
|
} else {
|
||||||
self.get("href").map(|x| x.as_str().unwrap_or("")).unwrap_or("")
|
self.get("href").and_then(|x| x.as_str()).ok_or(FieldErr("href"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,15 +70,18 @@ impl Link for serde_json::Value {
|
||||||
|
|
||||||
#[cfg(feature = "unstructured")]
|
#[cfg(feature = "unstructured")]
|
||||||
impl LinkMut for serde_json::Value {
|
impl LinkMut for serde_json::Value {
|
||||||
fn set_href(mut self, href: &str) -> Self {
|
fn set_href(mut self, href: Option<&str>) -> Self {
|
||||||
match &mut self {
|
match &mut self {
|
||||||
serde_json::Value::Object(map) => {
|
serde_json::Value::Object(map) => {
|
||||||
map.insert(
|
match href {
|
||||||
"href".to_string(),
|
Some(href) => map.insert(
|
||||||
serde_json::Value::String(href.to_string())
|
"href".to_string(),
|
||||||
);
|
serde_json::Value::String(href.to_string())
|
||||||
|
),
|
||||||
|
None => map.remove("href"),
|
||||||
|
};
|
||||||
},
|
},
|
||||||
x => *x = serde_json::Value::String(href.to_string()),
|
x => *x = serde_json::Value::String(href.unwrap_or_default().to_string()),
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ impl<T: apb::Base> From<apb::Node<T>> for Audience {
|
||||||
Audience(
|
Audience(
|
||||||
match value {
|
match value {
|
||||||
apb::Node::Empty => vec![],
|
apb::Node::Empty => vec![],
|
||||||
apb::Node::Link(l) => vec![l.href().to_string()],
|
apb::Node::Link(l) => l.href().map(|x| vec![x.to_string()]).unwrap_or_default(),
|
||||||
apb::Node::Object(o) => if let Ok(id) = o.id() { vec![id.to_string()] } else { vec![] },
|
apb::Node::Object(o) => if let Ok(id) = o.id() { vec![id.to_string()] } else { vec![] },
|
||||||
apb::Node::Array(arr) => arr.into_iter().filter_map(|l| l.id().str()).collect(),
|
apb::Node::Array(arr) => arr.into_iter().filter_map(|l| l.id().str()).collect(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ impl RichMention {
|
||||||
use apb::LinkMut;
|
use apb::LinkMut;
|
||||||
apb::new()
|
apb::new()
|
||||||
.set_link_type(Some(apb::LinkType::Mention))
|
.set_link_type(Some(apb::LinkType::Mention))
|
||||||
.set_href(&self.id)
|
.set_href(Some(&self.id))
|
||||||
.set_name(Some(&self.fqn))
|
.set_name(Some(&self.fqn))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -427,11 +427,13 @@ pub trait Fetchable : Sync + Send {
|
||||||
impl Fetchable for apb::Node<serde_json::Value> {
|
impl Fetchable for apb::Node<serde_json::Value> {
|
||||||
async fn fetch(&mut self, ctx: &crate::Context) -> Result<&mut Self, PullError> {
|
async fn fetch(&mut self, ctx: &crate::Context) -> Result<&mut Self, PullError> {
|
||||||
if let apb::Node::Link(uri) = self {
|
if let apb::Node::Link(uri) = self {
|
||||||
*self = crate::Context::request(Method::GET, uri.href(), None, ctx.base(), ctx.pkey(), ctx.domain())
|
if let Ok(href) = uri.href() {
|
||||||
.await?
|
*self = crate::Context::request(Method::GET, href, None, ctx.base(), ctx.pkey(), ctx.domain())
|
||||||
.json::<serde_json::Value>()
|
.await?
|
||||||
.await?
|
.json::<serde_json::Value>()
|
||||||
.into();
|
.await?
|
||||||
|
.into();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(self)
|
Ok(self)
|
||||||
|
|
|
@ -77,7 +77,7 @@ impl Normalizer for crate::Context {
|
||||||
},
|
},
|
||||||
Node::Link(l) => crate::model::attachment::ActiveModel {
|
Node::Link(l) => crate::model::attachment::ActiveModel {
|
||||||
internal: sea_orm::ActiveValue::NotSet,
|
internal: sea_orm::ActiveValue::NotSet,
|
||||||
url: Set(l.href().to_string()),
|
url: Set(l.href().unwrap_or_default().to_string()),
|
||||||
object: Set(object_model.internal),
|
object: Set(object_model.internal),
|
||||||
document_type: Set(apb::DocumentType::Page),
|
document_type: Set(apb::DocumentType::Page),
|
||||||
name: Set(l.name().str()),
|
name: Set(l.name().str()),
|
||||||
|
@ -96,20 +96,22 @@ impl Normalizer for crate::Context {
|
||||||
Node::Empty | Node::Object(_) | Node::Array(_) => {},
|
Node::Empty | Node::Object(_) | Node::Array(_) => {},
|
||||||
Node::Link(l) => match l.link_type() {
|
Node::Link(l) => match l.link_type() {
|
||||||
Ok(apb::LinkType::Mention) => {
|
Ok(apb::LinkType::Mention) => {
|
||||||
if let Some(internal) = crate::model::actor::Entity::ap_to_internal(l.href(), tx).await? {
|
if let Ok(href) = l.href() {
|
||||||
let model = crate::model::mention::ActiveModel {
|
if let Some(internal) = crate::model::actor::Entity::ap_to_internal(href, tx).await? {
|
||||||
internal: NotSet,
|
let model = crate::model::mention::ActiveModel {
|
||||||
object: Set(object_model.internal),
|
internal: NotSet,
|
||||||
actor: Set(internal),
|
object: Set(object_model.internal),
|
||||||
};
|
actor: Set(internal),
|
||||||
crate::model::mention::Entity::insert(model)
|
};
|
||||||
.exec(tx)
|
crate::model::mention::Entity::insert(model)
|
||||||
.await?;
|
.exec(tx)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Ok(apb::LinkType::Hashtag) => {
|
Ok(apb::LinkType::Hashtag) => {
|
||||||
let hashtag = l.name()
|
let hashtag = l.name()
|
||||||
.unwrap_or_else(|_| l.href().split('/').last().unwrap_or_default())
|
.unwrap_or_else(|_| l.href().unwrap_or_default().split('/').last().unwrap_or_default()) // TODO maybe just fail?
|
||||||
.replace('#', "");
|
.replace('#', "");
|
||||||
let model = crate::model::hashtag::ActiveModel {
|
let model = crate::model::hashtag::ActiveModel {
|
||||||
internal: NotSet,
|
internal: NotSet,
|
||||||
|
|
|
@ -72,7 +72,7 @@ pub fn Object(
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
Ok(apb::LinkType::Mention) => {
|
Ok(apb::LinkType::Mention) => {
|
||||||
let uid = apb::Link::href(link.as_ref());
|
let uid = apb::Link::href(link.as_ref()).unwrap_or_default();
|
||||||
let mention = apb::Link::name(link.as_ref()).unwrap_or_default().replacen('@', "", 1);
|
let mention = apb::Link::name(link.as_ref()).unwrap_or_default().replacen('@', "", 1);
|
||||||
let (username, domain) = if let Some((username, server)) = mention.split_once('@') {
|
let (username, domain) = if let Some((username, server)) = mention.split_once('@') {
|
||||||
(username.to_string(), server.to_string())
|
(username.to_string(), server.to_string())
|
||||||
|
|
Loading…
Reference in a new issue