handle more date formats

This commit is contained in:
Robin Appelman 2024-09-16 11:24:06 +02:00
commit 730b7b8c7a
6 changed files with 26 additions and 16 deletions

View file

@ -24,7 +24,7 @@ pub struct LogLine<'a> {
pub level: LogLevel, pub level: LogLevel,
pub message: Cow<'a, str>, pub message: Cow<'a, str>,
pub exception: Option<Exception<'a>>, pub exception: Option<Exception<'a>>,
pub app: &'a str, pub app: Cow<'a, str>,
#[serde(with = "date")] #[serde(with = "date")]
pub time: OffsetDateTime, pub time: OffsetDateTime,
} }
@ -40,9 +40,12 @@ mod date {
use time::parsing::Parsable; use time::parsing::Parsable;
use time::{OffsetDateTime, PrimitiveDateTime}; use time::{OffsetDateTime, PrimitiveDateTime};
const FORMATS: &[&[BorrowedFormatItem]] = &[format_description!( const FORMATS: &[&[BorrowedFormatItem]] = &[
"[year]-[month]-[day] [hour]:[minute]:[second]" format_description!("[year]-[month]-[day] [hour]:[minute]:[second]"),
)]; format_description!(
"[month repr:long case_sensitive:false] [day], [year] [hour]:[minute]:[second]"
),
];
fn try_format(str: &str, format: &(impl Parsable + ?Sized)) -> Option<OffsetDateTime> { fn try_format(str: &str, format: &(impl Parsable + ?Sized)) -> Option<OffsetDateTime> {
if let Ok(date) = OffsetDateTime::parse(str, format) { if let Ok(date) = OffsetDateTime::parse(str, format) {

View file

@ -327,7 +327,7 @@ fn test_matcher() {
Some(MatchResult::Single(0)), Some(MatchResult::Single(0)),
matcher.match_log(&LogLine { matcher.match_log(&LogLine {
version: "29", version: "29",
app: "core", app: "core".into(),
level: LogLevel::Error, level: LogLevel::Error,
message: "Not allowed to rename a shared album".into(), message: "Not allowed to rename a shared album".into(),
exception: None, exception: None,
@ -339,7 +339,7 @@ fn test_matcher() {
Some(MatchResult::List(vec![3, 4])), Some(MatchResult::List(vec![3, 4])),
matcher.match_log(&LogLine { matcher.match_log(&LogLine {
version: "29", version: "29",
app: "core", app: "core".into(),
level: LogLevel::Error, level: LogLevel::Error,
message: "Not allowed to rename an album".into(), message: "Not allowed to rename an album".into(),
exception: None, exception: None,
@ -351,7 +351,7 @@ fn test_matcher() {
Some(MatchResult::Single(1)), Some(MatchResult::Single(1)),
matcher.match_log(&LogLine { matcher.match_log(&LogLine {
version: "29", version: "29",
app: "core", app: "core".into(),
level: LogLevel::Error, level: LogLevel::Error,
message: "You are not allowed to edit link shares that you don't own".into(), message: "You are not allowed to edit link shares that you don't own".into(),
exception: None, exception: None,
@ -363,7 +363,7 @@ fn test_matcher() {
None, None,
matcher.match_log(&LogLine { matcher.match_log(&LogLine {
version: "29", version: "29",
app: "core", app: "core".into(),
level: LogLevel::Info, level: LogLevel::Info,
message: "You are not allowed to edit link shares that you don't own".into(), message: "You are not allowed to edit link shares that you don't own".into(),
exception: None, exception: None,
@ -376,7 +376,7 @@ fn test_matcher() {
matcher.match_log( matcher.match_log(
&LogLine { &LogLine {
version: "29", version: "29",
app: "core", app: "core".into(),
level: LogLevel::Error, level: LogLevel::Error,
message: "Unsupported query value for mimetype: %/text, only values in the format \"mime/type\" or \"mime/%\" are supported".into(), message: "Unsupported query value for mimetype: %/text, only values in the format \"mime/type\" or \"mime/%\" are supported".into(),
exception: None, exception: None,
@ -390,7 +390,7 @@ fn test_matcher() {
matcher.match_log( matcher.match_log(
&LogLine { &LogLine {
version: "29", version: "29",
app: "core", app: "core".into(),
level: LogLevel::Error, level: LogLevel::Error,
message: "Unsupported query value for mimetype: %/text, only values in the format \"mime/type\" or \"mime/%\" are supported".into(), message: "Unsupported query value for mimetype: %/text, only values in the format \"mime/type\" or \"mime/%\" are supported".into(),
exception: Some(Exception { exception: Some(Exception {
@ -408,7 +408,7 @@ fn test_matcher() {
Some(MatchResult::Single(5)), Some(MatchResult::Single(5)),
matcher.match_log(&LogLine { matcher.match_log(&LogLine {
version: "29", version: "29",
app: "core", app: "core".into(),
level: LogLevel::Error, level: LogLevel::Error,
message: "Not allowed to rename 'foo to' to to2".into(), message: "Not allowed to rename 'foo to' to to2".into(),
exception: None, exception: None,

View file

@ -32,7 +32,7 @@ pub fn raw_logs<'a>(app: &'a App<'a>, lines: &[usize]) -> ScrollbarTable<'a> {
fn log_row<'a>(line: &'a LogLine<'a>) -> Row<'a> { fn log_row<'a>(line: &'a LogLine<'a>) -> Row<'a> {
Row::new([ Row::new([
Text::from(line.level.as_str()), Text::from(line.level.as_str()),
Text::from(line.app), Text::from(line.app.as_ref()),
Text::from(line.display()), Text::from(line.display()),
Text::from(format_time(line.time)).alignment(Alignment::Right), Text::from(format_time(line.time)).alignment(Alignment::Right),
]) ])

View file

@ -35,7 +35,7 @@ fn group_row<'a>(app: &'a App, group: &'a GroupedLines) -> Row<'a> {
Row::new([ Row::new([
Text::from(line.level.as_str()), Text::from(line.level.as_str()),
Text::from(line.app), Text::from(line.app.as_ref()),
Text::from(line.display()), Text::from(line.display()),
Text::from(group.sparkline.as_str()), Text::from(group.sparkline.as_str()),
Text::from(group.len().to_string()), Text::from(group.len().to_string()),

View file

@ -1,4 +1,3 @@
use std::iter::once;
use crate::app::{App, LogMatch}; use crate::app::{App, LogMatch};
use crate::logline::{FullLogLine, LogLine}; use crate::logline::{FullLogLine, LogLine};
use crate::ui::table::ScrollbarTableState; use crate::ui::table::ScrollbarTableState;
@ -6,6 +5,7 @@ use crate::ui::UI_HEADER_SIZE;
use crate::{copy_osc, parse_line_full}; use crate::{copy_osc, parse_line_full};
use derive_more::From; use derive_more::From;
use ratatui::widgets::TableState; use ratatui::widgets::TableState;
use std::iter::once;
#[derive(Clone, From, PartialEq)] #[derive(Clone, From, PartialEq)]
pub enum UiState<'a> { pub enum UiState<'a> {
@ -213,7 +213,11 @@ impl<'a> UiState<'a> {
UiState::MatchList(MatchListState { app, .. }) => { UiState::MatchList(MatchListState { app, .. }) => {
let mut total_height = 0; let mut total_height = 0;
let match_row_counts = app.matches.iter().map(|m| m.row_count()); let match_row_counts = app.matches.iter().map(|m| m.row_count());
for (index, row_count) in once(1).chain(match_row_counts).chain(once(1)).enumerate().skip(self.scroll_offset()) for (index, row_count) in once(1)
.chain(match_row_counts)
.chain(once(1))
.enumerate()
.skip(self.scroll_offset())
{ {
if total_height > row { if total_height > row {
return index - 1; return index - 1;

View file

@ -102,7 +102,10 @@ impl ScrollbarTableState {
pub fn scroll(&mut self, step: isize) { pub fn scroll(&mut self, step: isize) {
*self.table.offset_mut() = self.table.offset().saturating_add_signed(step); *self.table.offset_mut() = self.table.offset().saturating_add_signed(step);
let selected = self.selected().saturating_add_signed(step).min(self.count - 1); let selected = self
.selected()
.saturating_add_signed(step)
.min(self.count - 1);
self.table.select(Some(selected)); self.table.select(Some(selected));
self.scrollbar = self.scrollbar.position(selected); self.scrollbar = self.scrollbar.position(selected);
} }