Merge branch 'post_links'
format Build format has succeeded Details
build-natter Build build-natter has succeeded Details
rust-clippy Build rust-clippy has succeeded Details
rust-test Build rust-test has succeeded Details

This commit is contained in:
Tom Alexander 2023-12-23 21:40:37 -05:00
commit fdff5a667b
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
6 changed files with 160 additions and 2 deletions

67
Cargo.lock generated
View File

@ -193,6 +193,15 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "form_urlencoded"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
dependencies = [
"percent-encoding",
]
[[package]]
name = "funty"
version = "1.1.0"
@ -312,6 +321,16 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
[[package]]
name = "idna"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
dependencies = [
"unicode-bidi",
"unicode-normalization",
]
[[package]]
name = "include_dir"
version = "0.7.3"
@ -400,6 +419,7 @@ dependencies = [
"serde_json",
"tokio",
"toml",
"url",
"walkdir",
]
@ -455,6 +475,12 @@ dependencies = [
"walkdir",
]
[[package]]
name = "percent-encoding"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "pin-project-lite"
version = "0.2.13"
@ -584,6 +610,21 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "tinyvec"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.33.0"
@ -630,12 +671,38 @@ dependencies = [
"winnow",
]
[[package]]
name = "unicode-bidi"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416"
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-normalization"
version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
dependencies = [
"tinyvec",
]
[[package]]
name = "url"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
dependencies = [
"form_urlencoded",
"idna",
"percent-encoding",
]
[[package]]
name = "utf8parse"
version = "0.2.1"

View File

@ -31,6 +31,7 @@ serde = { version = "1.0.189", default-features = false, features = ["std", "der
serde_json = "1.0.107"
tokio = { version = "1.30.0", default-features = false, features = ["rt", "rt-multi-thread", "fs", "io-util"] }
toml = "0.8.2"
url = "2.5.0"
walkdir = "2.4.0"
# Optimized build for any sort of release.

View File

@ -1 +1 @@
<a href="{.raw_link}">{#.children}{>object/}{/.children}</a>
<a href="{.target}">{#.children}{>object/}{/.children}</a>

View File

@ -11,6 +11,7 @@ use super::RenderObject;
#[serde(tag = "type")]
#[serde(rename = "regular_link")]
pub(crate) struct RenderRegularLink {
target: String,
raw_link: String,
children: Vec<RenderObject>,
post_blank: organic::types::PostBlank,
@ -25,7 +26,13 @@ render!(RenderRegularLink, IRegularLink, original, render_context, {
ret
};
let target = original
.target
.generate_final_target(render_context.clone())?
.unwrap_or_else(|| "".to_owned());
Ok(RenderRegularLink {
target,
raw_link: original.raw_link.clone(),
children,
post_blank: original.post_blank,

View File

@ -16,6 +16,7 @@ pub(crate) enum CustomError {
DusterCompile(duster::renderer::CompileError),
DusterRender(duster::renderer::RenderError),
PathStripPrefix(std::path::StripPrefixError),
UrlParseError(url::ParseError),
}
impl From<std::io::Error> for CustomError {
@ -95,3 +96,9 @@ impl From<std::path::StripPrefixError> for CustomError {
CustomError::PathStripPrefix(value)
}
}
impl From<url::ParseError> for CustomError {
fn from(value: url::ParseError) -> Self {
CustomError::UrlParseError(value)
}
}

View File

@ -1,14 +1,18 @@
use organic::types::StandardProperties;
use url::Url;
use super::get_web_path;
use super::macros::intermediate;
use super::IObject;
use crate::context::RenderContext;
use crate::error::CustomError;
#[derive(Debug, Clone)]
pub(crate) struct IRegularLink {
pub(crate) raw_link: String,
pub(crate) children: Vec<IObject>,
pub(crate) target: LinkTarget,
pub(crate) post_blank: organic::types::PostBlank,
}
@ -25,10 +29,82 @@ intermediate!(
}
ret
};
let raw_link = original.get_raw_link();
let target = LinkTarget::from_string(&raw_link)?;
Ok(IRegularLink {
raw_link: original.get_raw_link().into_owned(),
raw_link: raw_link.into_owned(),
children,
target,
post_blank: original.get_post_blank(),
})
}
);
#[derive(Debug, Clone)]
pub(crate) enum LinkTarget {
Raw(String),
Post {
post_id: Option<String>,
subpath: 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())),
}
}
impl_from_string(input.as_ref())
}
pub(crate) fn generate_final_target(
&self,
render_context: RenderContext<'_>,
) -> Result<Option<String>, CustomError> {
match self {
LinkTarget::Raw(raw_link) => Ok(Some(raw_link.clone())),
LinkTarget::Post { post_id, subpath } => {
let path = post_id
.as_ref()
.map(|post_id| {
let path_to_post = render_context
.config
.get_relative_path_to_post(post_id)
.join(subpath);
get_web_path(
render_context.config,
render_context.output_root_directory,
render_context.output_file,
path_to_post,
)
})
.map_or(Ok(None), |r| r.map(Some))?;
Ok(path)
}
}
}
}