Compare commits
2 commits
65cfe8b28f
...
44a4b6a365
Author | SHA1 | Date | |
---|---|---|---|
44a4b6a365 | |||
acaf55f7ea |
3 changed files with 28 additions and 30 deletions
|
@ -87,8 +87,8 @@ pub async fn load() -> Result<Config> {
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
file.read_to_string(&mut buf)
|
file.read_to_string(&mut buf)
|
||||||
.await
|
.await
|
||||||
.with_context(|| "couldn't read configuration file")?;
|
.context("couldn't read configuration file")?;
|
||||||
toml::from_str(&buf).with_context(|| "couldn't parse configuration")
|
toml::from_str(&buf).context("couldn't parse configuration")
|
||||||
}
|
}
|
||||||
Err(err) => match err.kind() {
|
Err(err) => match err.kind() {
|
||||||
std::io::ErrorKind::NotFound => {
|
std::io::ErrorKind::NotFound => {
|
||||||
|
@ -104,7 +104,7 @@ pub async fn load() -> Result<Config> {
|
||||||
Ok(mut file) => file
|
Ok(mut file) => file
|
||||||
.write_all(
|
.write_all(
|
||||||
toml::to_string_pretty(&config)
|
toml::to_string_pretty(&config)
|
||||||
.with_context(|| "couldn't serialize configuration")?
|
.context("couldn't serialize configuration")?
|
||||||
.as_bytes(),
|
.as_bytes(),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
|
29
src/main.rs
29
src/main.rs
|
@ -141,7 +141,7 @@ async fn main() -> eyre::Result<()> {
|
||||||
|
|
||||||
let config = config::load()
|
let config = config::load()
|
||||||
.await
|
.await
|
||||||
.with_context(|| "couldn't load configuration")?;
|
.context("couldn't load configuration")?;
|
||||||
|
|
||||||
let mut tasks = JoinSet::new();
|
let mut tasks = JoinSet::new();
|
||||||
let mut cancellation_tokens = Vec::new();
|
let mut cancellation_tokens = Vec::new();
|
||||||
|
@ -154,7 +154,7 @@ async fn main() -> eyre::Result<()> {
|
||||||
let compressed = tokio::task::spawn_blocking(|| compress_epicly("static"))
|
let compressed = tokio::task::spawn_blocking(|| compress_epicly("static"))
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.with_context(|| "couldn't compress static")?;
|
.context("couldn't compress static")?;
|
||||||
|
|
||||||
let _handle = span.enter();
|
let _handle = span.enter();
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ async fn main() -> eyre::Result<()> {
|
||||||
tasks.spawn(async move {
|
tasks.spawn(async move {
|
||||||
watch(span, passed_token, Default::default())
|
watch(span, passed_token, Default::default())
|
||||||
.await
|
.await
|
||||||
.with_context(|| "failed to watch static")
|
.context("failed to watch static")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
});
|
});
|
||||||
cancellation_tokens.push(token);
|
cancellation_tokens.push(token);
|
||||||
|
@ -186,14 +186,14 @@ async fn main() -> eyre::Result<()> {
|
||||||
let load_cache = async {
|
let load_cache = async {
|
||||||
let mut cache_file = tokio::fs::File::open(&path)
|
let mut cache_file = tokio::fs::File::open(&path)
|
||||||
.await
|
.await
|
||||||
.with_context(|| "failed to open cache file")?;
|
.context("failed to open cache file")?;
|
||||||
let mut serialized = Vec::with_capacity(4096);
|
let mut serialized = Vec::with_capacity(4096);
|
||||||
cache_file
|
cache_file
|
||||||
.read_to_end(&mut serialized)
|
.read_to_end(&mut serialized)
|
||||||
.await
|
.await
|
||||||
.with_context(|| "failed to read cache file")?;
|
.context("failed to read cache file")?;
|
||||||
let cache = bitcode::deserialize(serialized.as_slice())
|
let cache =
|
||||||
.with_context(|| "failed to parse cache")?;
|
bitcode::deserialize(serialized.as_slice()).context("failed to parse cache")?;
|
||||||
Ok::<PostManager, color_eyre::Report>(PostManager::new_with_cache(
|
Ok::<PostManager, color_eyre::Report>(PostManager::new_with_cache(
|
||||||
config.posts_dir.clone(),
|
config.posts_dir.clone(),
|
||||||
config.render.clone(),
|
config.render.clone(),
|
||||||
|
@ -260,7 +260,7 @@ async fn main() -> eyre::Result<()> {
|
||||||
})?;
|
})?;
|
||||||
let local_addr = listener
|
let local_addr = listener
|
||||||
.local_addr()
|
.local_addr()
|
||||||
.with_context(|| "couldn't get socket address")?;
|
.context("couldn't get socket address")?;
|
||||||
info!("listening on http://{}", local_addr);
|
info!("listening on http://{}", local_addr);
|
||||||
|
|
||||||
let sigint = signal::ctrl_c();
|
let sigint = signal::ctrl_c();
|
||||||
|
@ -284,7 +284,7 @@ async fn main() -> eyre::Result<()> {
|
||||||
|
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
result = &mut server => {
|
result = &mut server => {
|
||||||
result.with_context(|| "failed to serve app")?;
|
result.context("failed to serve app")?;
|
||||||
},
|
},
|
||||||
_ = sigint => {
|
_ = sigint => {
|
||||||
info!("received SIGINT, exiting gracefully");
|
info!("received SIGINT, exiting gracefully");
|
||||||
|
@ -299,9 +299,9 @@ async fn main() -> eyre::Result<()> {
|
||||||
for token in cancellation_tokens {
|
for token in cancellation_tokens {
|
||||||
token.cancel();
|
token.cancel();
|
||||||
}
|
}
|
||||||
server.await.with_context(|| "failed to serve app")?;
|
server.await.context("failed to serve app")?;
|
||||||
while let Some(task) = tasks.join_next().await {
|
while let Some(task) = tasks.join_next().await {
|
||||||
task.with_context(|| "failed to join task")?;
|
task.context("failed to join task")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// write cache to file
|
// write cache to file
|
||||||
|
@ -311,15 +311,14 @@ async fn main() -> eyre::Result<()> {
|
||||||
});
|
});
|
||||||
if let Some(path) = config.cache_file.as_ref() {
|
if let Some(path) = config.cache_file.as_ref() {
|
||||||
let cache = posts.into_cache();
|
let cache = posts.into_cache();
|
||||||
let mut serialized =
|
let mut serialized = bitcode::serialize(&cache).context("failed to serialize cache")?;
|
||||||
bitcode::serialize(&cache).with_context(|| "failed to serialize cache")?;
|
|
||||||
let mut cache_file = tokio::fs::File::create(path)
|
let mut cache_file = tokio::fs::File::create(path)
|
||||||
.await
|
.await
|
||||||
.with_context(|| format!("failed to open cache at {}", path.display()))?;
|
.with_context(|| format!("failed to open cache at {}", path.display()))?;
|
||||||
cache_file
|
cache_file
|
||||||
.write_all(serialized.as_mut_slice())
|
.write_all(serialized.as_mut_slice())
|
||||||
.await
|
.await
|
||||||
.with_context(|| "failed to write cache to file")?;
|
.context("failed to write cache to file")?;
|
||||||
info!("wrote cache to {}", path.display());
|
info!("wrote cache to {}", path.display());
|
||||||
}
|
}
|
||||||
Ok::<(), color_eyre::Report>(())
|
Ok::<(), color_eyre::Report>(())
|
||||||
|
@ -336,7 +335,7 @@ async fn main() -> eyre::Result<()> {
|
||||||
|
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
result = cleanup => {
|
result = cleanup => {
|
||||||
result.with_context(|| "cleanup failed, oh well")?;
|
result.context("cleanup failed, oh well")?;
|
||||||
},
|
},
|
||||||
_ = sigint => {
|
_ = sigint => {
|
||||||
warn!("received second signal, exiting");
|
warn!("received second signal, exiting");
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
use std::hash::{DefaultHasher, Hash, Hasher};
|
use std::hash::{DefaultHasher, Hash, Hasher};
|
||||||
|
|
||||||
use scc::HashMap;
|
use scc::HashMap;
|
||||||
use serde::de::{SeqAccess, Visitor};
|
use serde::de::Visitor;
|
||||||
use serde::{ser::SerializeSeq, Deserialize, Deserializer, Serialize, Serializer};
|
use serde::ser::SerializeMap;
|
||||||
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
|
||||||
use crate::config::RenderConfig;
|
use crate::config::RenderConfig;
|
||||||
use crate::post::PostMetadata;
|
use crate::post::PostMetadata;
|
||||||
|
@ -113,15 +114,13 @@ impl Serialize for Cache {
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
let cache = self.clone().into_inner();
|
let cache = self.clone().into_inner();
|
||||||
let mut seq = serializer.serialize_seq(Some(cache.len()))?;
|
let mut map = serializer.serialize_map(Some(cache.len()))?;
|
||||||
let mut entry = cache.first_entry();
|
let mut entry = cache.first_entry();
|
||||||
while let Some(occupied) = entry {
|
while let Some(occupied) = entry {
|
||||||
let key = occupied.key().clone();
|
map.serialize_entry(occupied.key(), occupied.get())?;
|
||||||
let value = occupied.get().clone();
|
|
||||||
seq.serialize_element(&(key, value))?;
|
|
||||||
entry = occupied.next();
|
entry = occupied.next();
|
||||||
}
|
}
|
||||||
seq.end()
|
map.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,16 +137,16 @@ impl<'de> Deserialize<'de> for Cache {
|
||||||
write!(formatter, "meow")
|
write!(formatter, "meow")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
|
||||||
where
|
where
|
||||||
A: SeqAccess<'de>,
|
A: serde::de::MapAccess<'de>,
|
||||||
{
|
{
|
||||||
let cache = match seq.size_hint() {
|
let cache = match map.size_hint() {
|
||||||
Some(size) => HashMap::with_capacity(size),
|
Some(size) => HashMap::with_capacity(size),
|
||||||
None => HashMap::new(),
|
None => HashMap::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
while let Some((key, value)) = seq.next_element::<(String, CacheValue)>()? {
|
while let Some((key, value)) = map.next_entry::<String, CacheValue>()? {
|
||||||
cache.insert(key, value).ok();
|
cache.insert(key, value).ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,6 +154,6 @@ impl<'de> Deserialize<'de> for Cache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deserializer.deserialize_seq(CoolVisitor)
|
deserializer.deserialize_map(CoolVisitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue