Add support for target links.
This commit is contained in:
@@ -3,6 +3,7 @@ use url::Url;
|
||||
|
||||
use super::get_web_path;
|
||||
use super::macros::intermediate;
|
||||
use super::IntermediateContext;
|
||||
|
||||
use super::IObject;
|
||||
use crate::context::RenderContext;
|
||||
@@ -30,7 +31,8 @@ intermediate!(
|
||||
ret
|
||||
};
|
||||
let raw_link = original.get_raw_link();
|
||||
let target = LinkTarget::from_string(&raw_link)?;
|
||||
let target =
|
||||
LinkTarget::from_string(intermediate_context.clone(), raw_link.clone().into_owned())?;
|
||||
Ok(IRegularLink {
|
||||
raw_link: raw_link.into_owned(),
|
||||
children,
|
||||
@@ -47,38 +49,44 @@ pub(crate) enum LinkTarget {
|
||||
post_id: Option<String>,
|
||||
subpath: String,
|
||||
},
|
||||
Target {
|
||||
target_id: String,
|
||||
},
|
||||
}
|
||||
|
||||
impl LinkTarget {
|
||||
pub(crate) fn from_string<S: AsRef<str>>(input: S) -> Result<LinkTarget, CustomError> {
|
||||
fn impl_from_string(input: &str) -> Result<LinkTarget, CustomError> {
|
||||
let parsed = Url::parse(input);
|
||||
if let Err(url::ParseError::RelativeUrlWithoutBase) = parsed {
|
||||
// For URLs to targets.
|
||||
// TODO: This shouldn't be raw but instead a variant for targets.
|
||||
return Ok(LinkTarget::Raw(input.to_owned()));
|
||||
}
|
||||
let parsed = parsed?;
|
||||
match parsed.scheme() {
|
||||
"post" => {
|
||||
let post_id = parsed.host_str().map(str::to_owned);
|
||||
let subpath = {
|
||||
let subpath = parsed.path();
|
||||
if let Some(subpath) = subpath.strip_prefix('/') {
|
||||
subpath
|
||||
} else {
|
||||
subpath
|
||||
}
|
||||
};
|
||||
Ok(LinkTarget::Post {
|
||||
post_id,
|
||||
subpath: subpath.to_owned(),
|
||||
})
|
||||
}
|
||||
_ => Ok(LinkTarget::Raw(input.to_owned())),
|
||||
}
|
||||
pub(crate) fn from_string(
|
||||
intermediate_context: IntermediateContext<'_, '_>,
|
||||
input: String,
|
||||
) -> Result<LinkTarget, CustomError> {
|
||||
let parsed = Url::parse(&input);
|
||||
if let Err(url::ParseError::RelativeUrlWithoutBase) = parsed {
|
||||
let target_id = {
|
||||
let mut registry = intermediate_context.registry.lock().unwrap();
|
||||
let target_id = registry.get_target(input).to_owned();
|
||||
target_id
|
||||
};
|
||||
return Ok(LinkTarget::Target { target_id });
|
||||
}
|
||||
let parsed = parsed?;
|
||||
match parsed.scheme() {
|
||||
"post" => {
|
||||
let post_id = parsed.host_str().map(str::to_owned);
|
||||
let subpath = {
|
||||
let subpath = parsed.path();
|
||||
if let Some(subpath) = subpath.strip_prefix('/') {
|
||||
subpath
|
||||
} else {
|
||||
subpath
|
||||
}
|
||||
};
|
||||
Ok(LinkTarget::Post {
|
||||
post_id,
|
||||
subpath: subpath.to_owned(),
|
||||
})
|
||||
}
|
||||
_ => Ok(LinkTarget::Raw(input.to_owned())),
|
||||
}
|
||||
impl_from_string(input.as_ref())
|
||||
}
|
||||
|
||||
pub(crate) fn generate_final_target(
|
||||
@@ -105,6 +113,14 @@ impl LinkTarget {
|
||||
.map_or(Ok(None), |r| r.map(Some))?;
|
||||
Ok(path)
|
||||
}
|
||||
LinkTarget::Target { target_id } => Ok(Some(format!(
|
||||
"#{}{}",
|
||||
render_context
|
||||
.id_addition
|
||||
.map(|id_addition| format!("sec{}.", id_addition))
|
||||
.unwrap_or_default(),
|
||||
target_id
|
||||
))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user