mirror of
https://git.asonix.dog/asonix/pict-rs
synced 2024-11-09 22:14:59 +00:00
Use color-eyre
This commit is contained in:
parent
1291bf8beb
commit
eb5e39c634
13 changed files with 211 additions and 102 deletions
95
Cargo.lock
generated
95
Cargo.lock
generated
|
@ -219,6 +219,15 @@ dependencies = [
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "addr2line"
|
||||||
|
version = "0.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b"
|
||||||
|
dependencies = [
|
||||||
|
"gimli",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "adler"
|
name = "adler"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
|
@ -372,6 +381,21 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "backtrace"
|
||||||
|
version = "0.3.64"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5e121dee8023ce33ab248d9ce1493df03c3b38a659b240096fcbd7048ff9c31f"
|
||||||
|
dependencies = [
|
||||||
|
"addr2line",
|
||||||
|
"cc",
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"miniz_oxide",
|
||||||
|
"object",
|
||||||
|
"rustc-demangle",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.13.0"
|
version = "0.13.0"
|
||||||
|
@ -498,6 +522,33 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "color-eyre"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ebf286c900a6d5867aeff75cfee3192857bb7f24b547d4f0df2ed6baa812c90"
|
||||||
|
dependencies = [
|
||||||
|
"backtrace",
|
||||||
|
"color-spantrace",
|
||||||
|
"eyre",
|
||||||
|
"indenter",
|
||||||
|
"once_cell",
|
||||||
|
"owo-colors",
|
||||||
|
"tracing-error",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "color-spantrace"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1ba75b3d9449ecdccb27ecbc479fdc0b87fa2dd43d2f8298f9bf0e59aacc8dce"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"owo-colors",
|
||||||
|
"tracing-core",
|
||||||
|
"tracing-error",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "config"
|
name = "config"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
|
@ -734,6 +785,16 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "eyre"
|
||||||
|
version = "0.6.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9289ed2c0440a6536e65119725cf91fc2c6b5e513bfd2e36e1134d7cca6ca12f"
|
||||||
|
dependencies = [
|
||||||
|
"indenter",
|
||||||
|
"once_cell",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fake-simd"
|
name = "fake-simd"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
|
@ -926,6 +987,12 @@ dependencies = [
|
||||||
"wasi 0.10.2+wasi-snapshot-preview1",
|
"wasi 0.10.2+wasi-snapshot-preview1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gimli"
|
||||||
|
version = "0.26.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "h2"
|
name = "h2"
|
||||||
version = "0.3.12"
|
version = "0.3.12"
|
||||||
|
@ -1122,6 +1189,12 @@ dependencies = [
|
||||||
"unicode-normalization",
|
"unicode-normalization",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indenter"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "1.8.0"
|
version = "1.8.0"
|
||||||
|
@ -1403,6 +1476,15 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "object"
|
||||||
|
version = "0.27.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.10.0"
|
version = "1.10.0"
|
||||||
|
@ -1489,6 +1571,12 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "owo-colors"
|
||||||
|
version = "3.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5e72e30578e0d0993c8ae20823dd9cff2bc5517d2f586a8aef462a581e8a03eb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.11.2"
|
version = "0.11.2"
|
||||||
|
@ -1621,6 +1709,7 @@ dependencies = [
|
||||||
"awc",
|
"awc",
|
||||||
"base64",
|
"base64",
|
||||||
"clap",
|
"clap",
|
||||||
|
"color-eyre",
|
||||||
"config",
|
"config",
|
||||||
"console-subscriber",
|
"console-subscriber",
|
||||||
"dashmap",
|
"dashmap",
|
||||||
|
@ -1997,6 +2086,12 @@ dependencies = [
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-demangle"
|
||||||
|
version = "0.1.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_version"
|
name = "rustc_version"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
|
|
@ -28,6 +28,7 @@ async-trait = "0.1.51"
|
||||||
awc = { version = "3.0.0", default-features = false, features = ["rustls"] }
|
awc = { version = "3.0.0", default-features = false, features = ["rustls"] }
|
||||||
base64 = "0.13.0"
|
base64 = "0.13.0"
|
||||||
clap = { version = "3.1.6", features = ["derive"] }
|
clap = { version = "3.1.6", features = ["derive"] }
|
||||||
|
color-eyre = "0.6"
|
||||||
config = "0.12.0"
|
config = "0.12.0"
|
||||||
console-subscriber = "0.1"
|
console-subscriber = "0.1"
|
||||||
dashmap = "5.1.0"
|
dashmap = "5.1.0"
|
||||||
|
@ -76,9 +77,9 @@ uuid = { version = "0.8.2", features = ["v4", "serde"] }
|
||||||
[dependencies.tracing-actix-web]
|
[dependencies.tracing-actix-web]
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["emit_event_on_error", "opentelemetry_0_17"]
|
features = ["opentelemetry_0_17"]
|
||||||
|
|
||||||
[dependencies.tracing-awc]
|
[dependencies.tracing-awc]
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["emit_event_on_error", "opentelemetry_0_17"]
|
features = ["opentelemetry_0_17"]
|
||||||
|
|
|
@ -13,7 +13,7 @@ pub(crate) use commandline::Operation;
|
||||||
pub(crate) use file::{ConfigFile as Configuration, OpenTelemetry, Repo, Sled, Tracing};
|
pub(crate) use file::{ConfigFile as Configuration, OpenTelemetry, Repo, Sled, Tracing};
|
||||||
pub(crate) use primitives::{Filesystem, ImageFormat, LogFormat, ObjectStorage, Store};
|
pub(crate) use primitives::{Filesystem, ImageFormat, LogFormat, ObjectStorage, Store};
|
||||||
|
|
||||||
pub(crate) fn configure() -> anyhow::Result<(Configuration, Operation)> {
|
pub(crate) fn configure() -> color_eyre::Result<(Configuration, Operation)> {
|
||||||
let Output {
|
let Output {
|
||||||
config_format,
|
config_format,
|
||||||
operation,
|
operation,
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::{
|
||||||
config::primitives::{ImageFormat, LogFormat, Store, Targets},
|
config::primitives::{ImageFormat, LogFormat, Store, Targets},
|
||||||
serde_str::Serde,
|
serde_str::Serde,
|
||||||
};
|
};
|
||||||
use std::{collections::HashSet, net::SocketAddr, path::PathBuf};
|
use std::{collections::BTreeSet, net::SocketAddr, path::PathBuf};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||||
|
@ -94,7 +94,7 @@ pub(crate) struct Media {
|
||||||
|
|
||||||
pub(crate) enable_silent_video: bool,
|
pub(crate) enable_silent_video: bool,
|
||||||
|
|
||||||
pub(crate) filters: HashSet<String>,
|
pub(crate) filters: BTreeSet<String>,
|
||||||
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub(crate) format: Option<ImageFormat>,
|
pub(crate) format: Option<ImageFormat>,
|
||||||
|
|
87
src/error.rs
87
src/error.rs
|
@ -1,50 +1,31 @@
|
||||||
use actix_web::{http::StatusCode, HttpResponse, ResponseError};
|
use actix_web::{http::StatusCode, HttpResponse, ResponseError};
|
||||||
use tracing_error::SpanTrace;
|
use color_eyre::Report;
|
||||||
|
|
||||||
pub(crate) struct Error {
|
pub(crate) struct Error {
|
||||||
context: SpanTrace,
|
inner: color_eyre::Report,
|
||||||
kind: UploadError,
|
}
|
||||||
|
|
||||||
|
impl Error {
|
||||||
|
fn kind(&self) -> Option<&UploadError> {
|
||||||
|
self.inner.downcast_ref()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for Error {
|
impl std::fmt::Debug for Error {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
writeln!(f, "{}", self.kind)
|
std::fmt::Debug::fmt(&self.inner, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for Error {
|
impl std::fmt::Display for Error {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
writeln!(f, "{}", self.kind)?;
|
std::fmt::Display::fmt(&self.inner, f)
|
||||||
writeln!(f)?;
|
|
||||||
|
|
||||||
writeln!(f, "Chain:")?;
|
|
||||||
fmt_chain(f, &self.kind)?;
|
|
||||||
|
|
||||||
writeln!(f)?;
|
|
||||||
writeln!(f, "Spantrace:")?;
|
|
||||||
std::fmt::Display::fmt(&self.context, f)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fmt_chain(
|
|
||||||
f: &mut std::fmt::Formatter<'_>,
|
|
||||||
err: &dyn std::error::Error,
|
|
||||||
) -> Result<usize, std::fmt::Error> {
|
|
||||||
let count = if let Some(source) = std::error::Error::source(err) {
|
|
||||||
fmt_chain(f, source)?
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
write!(f, "\t{}. ", count)?;
|
|
||||||
writeln!(f, "{}", err)?;
|
|
||||||
|
|
||||||
Ok(count + 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::error::Error for Error {
|
impl std::error::Error for Error {
|
||||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
self.kind.source()
|
self.inner.source()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,8 +35,7 @@ where
|
||||||
{
|
{
|
||||||
fn from(error: T) -> Self {
|
fn from(error: T) -> Self {
|
||||||
Error {
|
Error {
|
||||||
kind: UploadError::from(error),
|
inner: Report::from(UploadError::from(error)),
|
||||||
context: SpanTrace::capture(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,25 +138,38 @@ impl From<tokio::sync::AcquireError> for UploadError {
|
||||||
|
|
||||||
impl ResponseError for Error {
|
impl ResponseError for Error {
|
||||||
fn status_code(&self) -> StatusCode {
|
fn status_code(&self) -> StatusCode {
|
||||||
match self.kind {
|
match self.kind() {
|
||||||
UploadError::DuplicateAlias
|
Some(
|
||||||
| UploadError::Limit(_)
|
UploadError::DuplicateAlias
|
||||||
| UploadError::NoFiles
|
| UploadError::Limit(_)
|
||||||
| UploadError::Upload(_) => StatusCode::BAD_REQUEST,
|
| UploadError::NoFiles
|
||||||
UploadError::Sled(crate::repo::sled::SledError::Missing)
|
| UploadError::Upload(_),
|
||||||
| UploadError::MissingAlias => StatusCode::NOT_FOUND,
|
) => StatusCode::BAD_REQUEST,
|
||||||
UploadError::InvalidToken => StatusCode::FORBIDDEN,
|
Some(
|
||||||
UploadError::Range => StatusCode::RANGE_NOT_SATISFIABLE,
|
UploadError::Sled(crate::repo::sled::SledError::Missing)
|
||||||
|
| UploadError::MissingAlias,
|
||||||
|
) => StatusCode::NOT_FOUND,
|
||||||
|
Some(UploadError::InvalidToken) => StatusCode::FORBIDDEN,
|
||||||
|
Some(UploadError::Range) => StatusCode::RANGE_NOT_SATISFIABLE,
|
||||||
_ => StatusCode::INTERNAL_SERVER_ERROR,
|
_ => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn error_response(&self) -> HttpResponse {
|
fn error_response(&self) -> HttpResponse {
|
||||||
HttpResponse::build(self.status_code())
|
if let Some(kind) = self.kind() {
|
||||||
.content_type("application/json")
|
HttpResponse::build(self.status_code())
|
||||||
.body(
|
.content_type("application/json")
|
||||||
serde_json::to_string(&serde_json::json!({ "msg": self.kind.to_string() }))
|
.body(
|
||||||
.unwrap_or_else(|_| r#"{"msg":"Request failed"}"#.to_string()),
|
serde_json::to_string(&serde_json::json!({ "msg": kind.to_string() }))
|
||||||
)
|
.unwrap_or_else(|_| r#"{"msg":"Request failed"}"#.to_string()),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
HttpResponse::build(self.status_code())
|
||||||
|
.content_type("application/json")
|
||||||
|
.body(
|
||||||
|
serde_json::to_string(&serde_json::json!({ "msg": "Unknown error" }))
|
||||||
|
.unwrap_or_else(|_| r#"{"msg":"Request failed"}"#.to_string()),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,9 @@ use tracing_subscriber::{
|
||||||
fmt::format::FmtSpan, layer::SubscriberExt, registry::LookupSpan, Layer, Registry,
|
fmt::format::FmtSpan, layer::SubscriberExt, registry::LookupSpan, Layer, Registry,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(super) fn init_tracing(tracing: &Tracing) -> anyhow::Result<()> {
|
pub(super) fn init_tracing(tracing: &Tracing) -> color_eyre::Result<()> {
|
||||||
|
color_eyre::install()?;
|
||||||
|
|
||||||
LogTracer::init()?;
|
LogTracer::init()?;
|
||||||
|
|
||||||
opentelemetry::global::set_text_map_propagator(TraceContextPropagator::new());
|
opentelemetry::global::set_text_map_propagator(TraceContextPropagator::new());
|
||||||
|
@ -28,7 +30,7 @@ pub(super) fn init_tracing(tracing: &Tracing) -> anyhow::Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_format<F>(format_layer: F, tracing: &Tracing) -> anyhow::Result<()>
|
fn with_format<F>(format_layer: F, tracing: &Tracing) -> color_eyre::Result<()>
|
||||||
where
|
where
|
||||||
F: Layer<Registry> + Send + Sync,
|
F: Layer<Registry> + Send + Sync,
|
||||||
{
|
{
|
||||||
|
@ -53,7 +55,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_subscriber<S>(subscriber: S, otel: &OpenTelemetry) -> anyhow::Result<()>
|
fn with_subscriber<S>(subscriber: S, otel: &OpenTelemetry) -> color_eyre::Result<()>
|
||||||
where
|
where
|
||||||
S: SubscriberExt + Send + Sync,
|
S: SubscriberExt + Send + Sync,
|
||||||
for<'a> S: LookupSpan<'a>,
|
for<'a> S: LookupSpan<'a>,
|
||||||
|
|
14
src/main.rs
14
src/main.rs
|
@ -11,7 +11,7 @@ use futures_util::{
|
||||||
};
|
};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashSet,
|
collections::BTreeSet,
|
||||||
future::ready,
|
future::ready,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
|
@ -263,7 +263,7 @@ type ProcessQuery = Vec<(String, String)>;
|
||||||
fn prepare_process(
|
fn prepare_process(
|
||||||
query: web::Query<ProcessQuery>,
|
query: web::Query<ProcessQuery>,
|
||||||
ext: &str,
|
ext: &str,
|
||||||
filters: &HashSet<String>,
|
filters: &BTreeSet<String>,
|
||||||
) -> Result<(ImageFormat, Alias, PathBuf, Vec<String>), Error> {
|
) -> Result<(ImageFormat, Alias, PathBuf, Vec<String>), Error> {
|
||||||
let (alias, operations) =
|
let (alias, operations) =
|
||||||
query
|
query
|
||||||
|
@ -306,7 +306,7 @@ async fn process_details<S: Store>(
|
||||||
ext: web::Path<String>,
|
ext: web::Path<String>,
|
||||||
manager: web::Data<UploadManager>,
|
manager: web::Data<UploadManager>,
|
||||||
store: web::Data<S>,
|
store: web::Data<S>,
|
||||||
filters: web::Data<HashSet<String>>,
|
filters: web::Data<BTreeSet<String>>,
|
||||||
) -> Result<HttpResponse, Error> {
|
) -> Result<HttpResponse, Error> {
|
||||||
let (_, alias, thumbnail_path, _) = prepare_process(query, ext.as_str(), &filters)?;
|
let (_, alias, thumbnail_path, _) = prepare_process(query, ext.as_str(), &filters)?;
|
||||||
|
|
||||||
|
@ -330,7 +330,7 @@ async fn process<S: Store + 'static>(
|
||||||
ext: web::Path<String>,
|
ext: web::Path<String>,
|
||||||
manager: web::Data<UploadManager>,
|
manager: web::Data<UploadManager>,
|
||||||
store: web::Data<S>,
|
store: web::Data<S>,
|
||||||
filters: web::Data<HashSet<String>>,
|
filters: web::Data<BTreeSet<String>>,
|
||||||
) -> Result<HttpResponse, Error> {
|
) -> Result<HttpResponse, Error> {
|
||||||
let (format, alias, thumbnail_path, thumbnail_args) =
|
let (format, alias, thumbnail_path, thumbnail_args) =
|
||||||
prepare_process(query, ext.as_str(), &filters)?;
|
prepare_process(query, ext.as_str(), &filters)?;
|
||||||
|
@ -635,7 +635,7 @@ fn build_reqwest_client() -> reqwest::Result<reqwest::Client> {
|
||||||
async fn launch<S: Store + Clone + 'static>(
|
async fn launch<S: Store + Clone + 'static>(
|
||||||
manager: UploadManager,
|
manager: UploadManager,
|
||||||
store: S,
|
store: S,
|
||||||
) -> anyhow::Result<()> {
|
) -> color_eyre::Result<()> {
|
||||||
// Create a new Multipart Form validator
|
// Create a new Multipart Form validator
|
||||||
//
|
//
|
||||||
// This form is expecting a single array field, 'images' with at most 10 files in it
|
// This form is expecting a single array field, 'images' with at most 10 files in it
|
||||||
|
@ -769,7 +769,7 @@ async fn migrate_inner<S1>(
|
||||||
repo: &Repo,
|
repo: &Repo,
|
||||||
from: S1,
|
from: S1,
|
||||||
to: &config::Store,
|
to: &config::Store,
|
||||||
) -> anyhow::Result<()>
|
) -> color_eyre::Result<()>
|
||||||
where
|
where
|
||||||
S1: Store,
|
S1: Store,
|
||||||
{
|
{
|
||||||
|
@ -806,7 +806,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::main]
|
#[actix_rt::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> color_eyre::Result<()> {
|
||||||
init_tracing(&CONFIG.tracing)?;
|
init_tracing(&CONFIG.tracing)?;
|
||||||
|
|
||||||
let repo = Repo::open(CONFIG.repo.clone())?;
|
let repo = Repo::open(CONFIG.repo.clone())?;
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
use crate::UploadError;
|
use crate::Error;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
mod s034;
|
mod s034;
|
||||||
|
|
||||||
type SledIter = Box<dyn Iterator<Item = Result<(Vec<u8>, Vec<u8>), UploadError>>>;
|
type SledIter = Box<dyn Iterator<Item = Result<(Vec<u8>, Vec<u8>), Error>>>;
|
||||||
|
|
||||||
trait SledDb {
|
trait SledDb {
|
||||||
type SledTree: SledTree;
|
type SledTree: SledTree;
|
||||||
|
|
||||||
fn open_tree(&self, name: &str) -> Result<Self::SledTree, UploadError>;
|
fn open_tree(&self, name: &str) -> Result<Self::SledTree, Error>;
|
||||||
|
|
||||||
fn self_tree(&self) -> &Self::SledTree;
|
fn self_tree(&self) -> &Self::SledTree;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ where
|
||||||
{
|
{
|
||||||
type SledTree = T::SledTree;
|
type SledTree = T::SledTree;
|
||||||
|
|
||||||
fn open_tree(&self, name: &str) -> Result<Self::SledTree, UploadError> {
|
fn open_tree(&self, name: &str) -> Result<Self::SledTree, Error> {
|
||||||
(*self).open_tree(name)
|
(*self).open_tree(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,11 +29,11 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
trait SledTree {
|
trait SledTree {
|
||||||
fn get<K>(&self, key: K) -> Result<Option<Vec<u8>>, UploadError>
|
fn get<K>(&self, key: K) -> Result<Option<Vec<u8>>, Error>
|
||||||
where
|
where
|
||||||
K: AsRef<[u8]>;
|
K: AsRef<[u8]>;
|
||||||
|
|
||||||
fn insert<K, V>(&self, key: K, value: V) -> Result<(), UploadError>
|
fn insert<K, V>(&self, key: K, value: V) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
K: AsRef<[u8]>,
|
K: AsRef<[u8]>,
|
||||||
V: AsRef<[u8]>;
|
V: AsRef<[u8]>;
|
||||||
|
@ -45,7 +45,7 @@ trait SledTree {
|
||||||
K: AsRef<[u8]>,
|
K: AsRef<[u8]>,
|
||||||
R: std::ops::RangeBounds<K>;
|
R: std::ops::RangeBounds<K>;
|
||||||
|
|
||||||
fn flush(&self) -> Result<(), UploadError>;
|
fn flush(&self) -> Result<(), Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct LatestDb {
|
pub(crate) struct LatestDb {
|
||||||
|
@ -60,7 +60,7 @@ impl LatestDb {
|
||||||
LatestDb { root_dir, version }
|
LatestDb { root_dir, version }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn migrate(self) -> Result<sled::Db, UploadError> {
|
pub(crate) fn migrate(self) -> Result<sled::Db, Error> {
|
||||||
let LatestDb { root_dir, version } = self;
|
let LatestDb { root_dir, version } = self;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
@ -89,7 +89,7 @@ impl DbVersion {
|
||||||
DbVersion::Fresh
|
DbVersion::Fresh
|
||||||
}
|
}
|
||||||
|
|
||||||
fn migrate(self, root: PathBuf) -> Result<sled::Db, UploadError> {
|
fn migrate(self, root: PathBuf) -> Result<sled::Db, Error> {
|
||||||
match self {
|
match self {
|
||||||
DbVersion::Sled034 | DbVersion::Fresh => s034::open(root),
|
DbVersion::Sled034 | DbVersion::Fresh => s034::open(root),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
|
error::Error,
|
||||||
migrate::{SledDb, SledIter, SledTree},
|
migrate::{SledDb, SledIter, SledTree},
|
||||||
UploadError,
|
|
||||||
};
|
};
|
||||||
use sled as sled034;
|
use sled as sled034;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
@ -26,7 +26,7 @@ pub(crate) fn migrating(base: PathBuf) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn open(mut base: PathBuf) -> Result<sled034::Db, UploadError> {
|
pub(crate) fn open(mut base: PathBuf) -> Result<sled034::Db, Error> {
|
||||||
base.push("sled");
|
base.push("sled");
|
||||||
base.push(SLED_034);
|
base.push(SLED_034);
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ pub(crate) fn open(mut base: PathBuf) -> Result<sled034::Db, UploadError> {
|
||||||
impl SledDb for sled034::Db {
|
impl SledDb for sled034::Db {
|
||||||
type SledTree = sled034::Tree;
|
type SledTree = sled034::Tree;
|
||||||
|
|
||||||
fn open_tree(&self, name: &str) -> Result<Self::SledTree, UploadError> {
|
fn open_tree(&self, name: &str) -> Result<Self::SledTree, Error> {
|
||||||
Ok(sled034::Db::open_tree(self, name)?)
|
Ok(sled034::Db::open_tree(self, name)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,14 +51,14 @@ impl SledDb for sled034::Db {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SledTree for sled034::Tree {
|
impl SledTree for sled034::Tree {
|
||||||
fn get<K>(&self, key: K) -> Result<Option<Vec<u8>>, UploadError>
|
fn get<K>(&self, key: K) -> Result<Option<Vec<u8>>, Error>
|
||||||
where
|
where
|
||||||
K: AsRef<[u8]>,
|
K: AsRef<[u8]>,
|
||||||
{
|
{
|
||||||
Ok(sled034::Tree::get(self, key)?.map(|v| Vec::from(v.as_ref())))
|
Ok(sled034::Tree::get(self, key)?.map(|v| Vec::from(v.as_ref())))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert<K, V>(&self, key: K, value: V) -> Result<(), UploadError>
|
fn insert<K, V>(&self, key: K, value: V) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
K: AsRef<[u8]>,
|
K: AsRef<[u8]>,
|
||||||
V: AsRef<[u8]>,
|
V: AsRef<[u8]>,
|
||||||
|
@ -69,7 +69,7 @@ impl SledTree for sled034::Tree {
|
||||||
fn iter(&self) -> SledIter {
|
fn iter(&self) -> SledIter {
|
||||||
Box::new(sled034::Tree::iter(self).map(|res| {
|
Box::new(sled034::Tree::iter(self).map(|res| {
|
||||||
res.map(|(k, v)| (k.as_ref().to_vec(), v.as_ref().to_vec()))
|
res.map(|(k, v)| (k.as_ref().to_vec(), v.as_ref().to_vec()))
|
||||||
.map_err(UploadError::from)
|
.map_err(Error::from)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,13 +80,11 @@ impl SledTree for sled034::Tree {
|
||||||
{
|
{
|
||||||
Box::new(sled034::Tree::range(self, range).map(|res| {
|
Box::new(sled034::Tree::range(self, range).map(|res| {
|
||||||
res.map(|(k, v)| (k.as_ref().to_vec(), v.as_ref().to_vec()))
|
res.map(|(k, v)| (k.as_ref().to_vec(), v.as_ref().to_vec()))
|
||||||
.map_err(UploadError::from)
|
.map_err(Error::from)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&self) -> Result<(), UploadError> {
|
fn flush(&self) -> Result<(), Error> {
|
||||||
sled034::Tree::flush(self)
|
sled034::Tree::flush(self).map(|_| ()).map_err(Error::from)
|
||||||
.map(|_| ())
|
|
||||||
.map_err(UploadError::from)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub(crate) fn build_chain(
|
||||||
args: &[(String, String)],
|
args: &[(String, String)],
|
||||||
ext: &str,
|
ext: &str,
|
||||||
) -> Result<(PathBuf, Vec<String>), Error> {
|
) -> Result<(PathBuf, Vec<String>), Error> {
|
||||||
fn parse<P: Processor>(key: &str, value: &str) -> Result<Option<P>, UploadError> {
|
fn parse<P: Processor>(key: &str, value: &str) -> Result<Option<P>, Error> {
|
||||||
if key == P::NAME {
|
if key == P::NAME {
|
||||||
return Ok(Some(P::parse(key, value).ok_or(UploadError::ParsePath)?));
|
return Ok(Some(P::parse(key, value).ok_or(UploadError::ParsePath)?));
|
||||||
}
|
}
|
||||||
|
|
10
src/repo.rs
10
src/repo.rs
|
@ -120,7 +120,7 @@ pub(crate) trait AliasRepo {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Repo {
|
impl Repo {
|
||||||
pub(crate) fn open(config: config::Repo) -> anyhow::Result<Self> {
|
pub(crate) fn open(config: config::Repo) -> color_eyre::Result<Self> {
|
||||||
match config {
|
match config {
|
||||||
config::Repo::Sled(config::Sled {
|
config::Repo::Sled(config::Sled {
|
||||||
mut path,
|
mut path,
|
||||||
|
@ -139,7 +139,7 @@ impl Repo {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
pub(crate) async fn from_db(&self, db: ::sled::Db) -> anyhow::Result<()> {
|
pub(crate) async fn from_db(&self, db: ::sled::Db) -> color_eyre::Result<()> {
|
||||||
if self.has_migrated().await? {
|
if self.has_migrated().await? {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -161,13 +161,13 @@ impl Repo {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn has_migrated(&self) -> anyhow::Result<bool> {
|
async fn has_migrated(&self) -> color_eyre::Result<bool> {
|
||||||
match self {
|
match self {
|
||||||
Self::Sled(repo) => Ok(repo.get(REPO_MIGRATION_O1).await?.is_some()),
|
Self::Sled(repo) => Ok(repo.get(REPO_MIGRATION_O1).await?.is_some()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn mark_migrated(&self) -> anyhow::Result<()> {
|
async fn mark_migrated(&self) -> color_eyre::Result<()> {
|
||||||
match self {
|
match self {
|
||||||
Self::Sled(repo) => {
|
Self::Sled(repo) => {
|
||||||
repo.set(REPO_MIGRATION_O1, b"1".to_vec().into()).await?;
|
repo.set(REPO_MIGRATION_O1, b"1".to_vec().into()).await?;
|
||||||
|
@ -182,7 +182,7 @@ const REPO_MIGRATION_O1: &[u8] = b"repo-migration-01";
|
||||||
const STORE_MIGRATION_PROGRESS: &[u8] = b"store-migration-progress";
|
const STORE_MIGRATION_PROGRESS: &[u8] = b"store-migration-progress";
|
||||||
const GENERATOR_KEY: &[u8] = b"last-path";
|
const GENERATOR_KEY: &[u8] = b"last-path";
|
||||||
|
|
||||||
async fn migrate_hash<T>(repo: &T, old: &old::Old, hash: ::sled::IVec) -> anyhow::Result<()>
|
async fn migrate_hash<T>(repo: &T, old: &old::Old, hash: ::sled::IVec) -> color_eyre::Result<()>
|
||||||
where
|
where
|
||||||
T: IdentifierRepo + HashRepo + AliasRepo + SettingsRepo,
|
T: IdentifierRepo + HashRepo + AliasRepo + SettingsRepo,
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,9 +17,19 @@
|
||||||
// - Settings Tree
|
// - Settings Tree
|
||||||
// - store-migration-progress -> Path Tree Key
|
// - store-migration-progress -> Path Tree Key
|
||||||
|
|
||||||
|
use super::{Alias, DeleteToken, Details};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use super::{Alias, DeleteToken, Details};
|
#[derive(Debug)]
|
||||||
|
struct OldDbError(&'static str);
|
||||||
|
|
||||||
|
impl std::fmt::Display for OldDbError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{}", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for OldDbError {}
|
||||||
|
|
||||||
pub(super) struct Old {
|
pub(super) struct Old {
|
||||||
alias_tree: ::sled::Tree,
|
alias_tree: ::sled::Tree,
|
||||||
|
@ -32,7 +42,7 @@ pub(super) struct Old {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Old {
|
impl Old {
|
||||||
pub(super) fn open(db: sled::Db) -> anyhow::Result<Self> {
|
pub(super) fn open(db: sled::Db) -> color_eyre::Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
alias_tree: db.open_tree("alias")?,
|
alias_tree: db.open_tree("alias")?,
|
||||||
filename_tree: db.open_tree("filename")?,
|
filename_tree: db.open_tree("filename")?,
|
||||||
|
@ -44,7 +54,7 @@ impl Old {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn setting(&self, key: &[u8]) -> anyhow::Result<Option<sled::IVec>> {
|
pub(super) fn setting(&self, key: &[u8]) -> color_eyre::Result<Option<sled::IVec>> {
|
||||||
Ok(self.settings_tree.get(key)?)
|
Ok(self.settings_tree.get(key)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,11 +65,14 @@ impl Old {
|
||||||
.filter_map(|res| res.ok())
|
.filter_map(|res| res.ok())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn details(&self, hash: &sled::IVec) -> anyhow::Result<Vec<(sled::IVec, Details)>> {
|
pub(super) fn details(
|
||||||
|
&self,
|
||||||
|
hash: &sled::IVec,
|
||||||
|
) -> color_eyre::Result<Vec<(sled::IVec, Details)>> {
|
||||||
let filename = self
|
let filename = self
|
||||||
.main_tree
|
.main_tree
|
||||||
.get(hash)?
|
.get(hash)?
|
||||||
.ok_or_else(|| anyhow::anyhow!("missing filename"))?;
|
.ok_or(OldDbError("Missing filename"))?;
|
||||||
|
|
||||||
let filename = String::from_utf8_lossy(&filename);
|
let filename = String::from_utf8_lossy(&filename);
|
||||||
|
|
||||||
|
@ -81,22 +94,26 @@ impl Old {
|
||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn main_identifier(&self, hash: &sled::IVec) -> anyhow::Result<sled::IVec> {
|
pub(super) fn main_identifier(&self, hash: &sled::IVec) -> color_eyre::Result<sled::IVec> {
|
||||||
let filename = self
|
let filename = self
|
||||||
.main_tree
|
.main_tree
|
||||||
.get(hash)?
|
.get(hash)?
|
||||||
.ok_or_else(|| anyhow::anyhow!("Missing filename"))?;
|
.ok_or(OldDbError("Missing filename"))?;
|
||||||
|
|
||||||
self.identifier_tree
|
Ok(self
|
||||||
|
.identifier_tree
|
||||||
.get(filename)?
|
.get(filename)?
|
||||||
.ok_or_else(|| anyhow::anyhow!("Missing identifier"))
|
.ok_or(OldDbError("Missing identifier"))?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn variants(&self, hash: &sled::IVec) -> anyhow::Result<Vec<(PathBuf, sled::IVec)>> {
|
pub(super) fn variants(
|
||||||
|
&self,
|
||||||
|
hash: &sled::IVec,
|
||||||
|
) -> color_eyre::Result<Vec<(PathBuf, sled::IVec)>> {
|
||||||
let filename = self
|
let filename = self
|
||||||
.main_tree
|
.main_tree
|
||||||
.get(hash)?
|
.get(hash)?
|
||||||
.ok_or_else(|| anyhow::anyhow!("Missing filename"))?;
|
.ok_or(OldDbError("Missing filename"))?;
|
||||||
|
|
||||||
let filename_string = String::from_utf8_lossy(&filename);
|
let filename_string = String::from_utf8_lossy(&filename);
|
||||||
|
|
||||||
|
@ -126,11 +143,11 @@ impl Old {
|
||||||
pub(super) fn motion_identifier(
|
pub(super) fn motion_identifier(
|
||||||
&self,
|
&self,
|
||||||
hash: &sled::IVec,
|
hash: &sled::IVec,
|
||||||
) -> anyhow::Result<Option<sled::IVec>> {
|
) -> color_eyre::Result<Option<sled::IVec>> {
|
||||||
let filename = self
|
let filename = self
|
||||||
.main_tree
|
.main_tree
|
||||||
.get(hash)?
|
.get(hash)?
|
||||||
.ok_or_else(|| anyhow::anyhow!("Missing filename"))?;
|
.ok_or(OldDbError("Missing filename"))?;
|
||||||
|
|
||||||
let filename_string = String::from_utf8_lossy(&filename);
|
let filename_string = String::from_utf8_lossy(&filename);
|
||||||
|
|
||||||
|
@ -151,7 +168,7 @@ impl Old {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn delete_token(&self, alias: &Alias) -> anyhow::Result<Option<DeleteToken>> {
|
pub(super) fn delete_token(&self, alias: &Alias) -> color_eyre::Result<Option<DeleteToken>> {
|
||||||
let key = format!("{}/delete", alias);
|
let key = format!("{}/delete", alias);
|
||||||
|
|
||||||
if let Some(ivec) = self.alias_tree.get(key)? {
|
if let Some(ivec) = self.alias_tree.get(key)? {
|
||||||
|
|
|
@ -122,6 +122,9 @@ impl Store for ObjectStore {
|
||||||
|
|
||||||
let request_span = tracing::info_span!(parent: None, "Get Object");
|
let request_span = tracing::info_span!(parent: None, "Get Object");
|
||||||
|
|
||||||
|
// NOTE: isolating reqwest in it's own span is to prevent the request's span from getting
|
||||||
|
// smuggled into a long-lived task. Unfortunately, I am unable to create a minimal
|
||||||
|
// reproduction of this problem so I can't open a bug about it.
|
||||||
let request = request_span.in_scope(|| {
|
let request = request_span.in_scope(|| {
|
||||||
Client::request(
|
Client::request(
|
||||||
&self.client,
|
&self.client,
|
||||||
|
|
Loading…
Reference in a new issue