Skip to content

Commit ddf9042

Browse files
committed
node: Extract some formatting helpers into a module
1 parent 2985a10 commit ddf9042

File tree

5 files changed

+87
-43
lines changed

5 files changed

+87
-43
lines changed

node/src/manager/commands/copy.rs

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use diesel::{ExpressionMethods, JoinOnDsl, OptionalExtension, QueryDsl, RunQueryDsl};
2-
use std::{collections::HashMap, sync::Arc, time::SystemTime};
2+
use std::{collections::HashMap, sync::Arc};
33

44
use graph::{
55
components::store::{BlockStore as _, DeploymentId, DeploymentLocator},
@@ -19,8 +19,8 @@ use graph_store_postgres::{
1919
};
2020
use graph_store_postgres::{ConnectionPool, Shard, Store, SubgraphStore};
2121

22-
use crate::manager::deployment::DeploymentSearch;
2322
use crate::manager::display::List;
23+
use crate::manager::{deployment::DeploymentSearch, fmt};
2424

2525
type UtcDateTime = DateTime<Utc>;
2626

@@ -260,26 +260,6 @@ pub fn status(pools: HashMap<Shard, ConnectionPool>, dst: &DeploymentSearch) ->
260260
use catalog::active_copies as ac;
261261
use catalog::deployment_schemas as ds;
262262

263-
fn duration(start: &UtcDateTime, end: &Option<UtcDateTime>) -> String {
264-
let start = *start;
265-
let end = *end;
266-
267-
let end = end.unwrap_or(UtcDateTime::from(SystemTime::now()));
268-
let duration = end - start;
269-
270-
human_duration(duration)
271-
}
272-
273-
fn human_duration(duration: Duration) -> String {
274-
if duration.num_seconds() < 5 {
275-
format!("{}ms", duration.num_milliseconds())
276-
} else if duration.num_minutes() < 5 {
277-
format!("{}s", duration.num_seconds())
278-
} else {
279-
format!("{}m", duration.num_minutes())
280-
}
281-
}
282-
283263
let primary = pools
284264
.get(&*PRIMARY_SHARD)
285265
.ok_or_else(|| anyhow!("can not find deployment with id {}", dst))?;
@@ -336,7 +316,7 @@ pub fn status(pools: HashMap<Shard, ConnectionPool>, dst: &DeploymentSearch) ->
336316
state.dst.to_string(),
337317
state.target_block_number.to_string(),
338318
on_sync.to_str().to_string(),
339-
duration(&state.started_at, &state.finished_at),
319+
fmt::duration(&state.started_at, &state.finished_at),
340320
progress,
341321
];
342322
match (cancelled_at, state.cancelled_at) {
@@ -378,7 +358,7 @@ pub fn status(pools: HashMap<Shard, ConnectionPool>, dst: &DeploymentSearch) ->
378358
table.next_vid,
379359
table.target_vid,
380360
table.batch_size,
381-
human_duration(Duration::milliseconds(table.duration_ms)),
361+
fmt::human_duration(Duration::milliseconds(table.duration_ms)),
382362
);
383363
}
384364

node/src/manager/commands/prune.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,7 @@ use graph::{
1616
};
1717
use graph_store_postgres::{ConnectionPool, Store};
1818

19-
use crate::manager::{
20-
commands::stats::{abbreviate_table_name, show_stats},
21-
deployment::DeploymentSearch,
22-
};
19+
use crate::manager::{commands::stats::show_stats, deployment::DeploymentSearch, fmt};
2320

2421
struct Progress {
2522
start: Instant,
@@ -66,7 +63,7 @@ fn print_batch(
6663
};
6764
print!(
6865
"\r{:<30} | {:>10} | {:>9}s {phase}",
69-
abbreviate_table_name(table, 30),
66+
fmt::abbreviate(table, 30),
7067
total_rows,
7168
elapsed.as_secs()
7269
);

node/src/manager/commands/stats.rs

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::collections::HashSet;
33
use std::sync::Arc;
44

55
use crate::manager::deployment::DeploymentSearch;
6+
use crate::manager::fmt;
67
use diesel::r2d2::ConnectionManager;
78
use diesel::r2d2::PooledConnection;
89
use diesel::PgConnection;
@@ -51,19 +52,6 @@ pub async fn account_like(
5152
Ok(())
5253
}
5354

54-
pub fn abbreviate_table_name(table: &str, size: usize) -> String {
55-
if table.len() > size {
56-
let fragment = size / 2 - 2;
57-
let last = table.len() - fragment;
58-
let mut table = table.to_string();
59-
table.replace_range(fragment..last, "..");
60-
let table = table.trim().to_string();
61-
table
62-
} else {
63-
table.to_string()
64-
}
65-
}
66-
6755
pub fn show_stats(
6856
stats: &[VersionStats],
6957
account_like: HashSet<String>,
@@ -83,7 +71,7 @@ pub fn show_stats(
8371
fn print_stats(s: &VersionStats, account_like: bool) {
8472
println!(
8573
"{:<26} {:3} | {:>10} | {:>10} | {:>5.1}%",
86-
abbreviate_table_name(&s.tablename, 26),
74+
fmt::abbreviate(&s.tablename, 26),
8775
if account_like { "(a)" } else { " " },
8876
s.entities,
8977
s.versions,

node/src/manager/fmt.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
use std::time::SystemTime;
2+
3+
use graph::prelude::chrono::{DateTime, Duration, Local, Utc};
4+
5+
pub const NULL: &str = "ø";
6+
const CHECK: &str = "✓";
7+
8+
pub fn null() -> String {
9+
NULL.to_string()
10+
}
11+
12+
pub fn check() -> String {
13+
CHECK.to_string()
14+
}
15+
16+
pub trait MapOrNull<T> {
17+
fn map_or_null<F>(&self, f: F) -> String
18+
where
19+
F: FnOnce(&T) -> String;
20+
}
21+
22+
impl<T> MapOrNull<T> for Option<T> {
23+
fn map_or_null<F>(&self, f: F) -> String
24+
where
25+
F: FnOnce(&T) -> String,
26+
{
27+
self.as_ref()
28+
.map(|value| f(value))
29+
.unwrap_or_else(|| NULL.to_string())
30+
}
31+
}
32+
33+
/// Return the duration from `start` to `end` formatted using
34+
/// `human_duration`. Use now if `end` is `None`
35+
pub fn duration(start: &DateTime<Utc>, end: &Option<DateTime<Utc>>) -> String {
36+
let start = *start;
37+
let end = *end;
38+
39+
let end = end.unwrap_or(DateTime::<Utc>::from(SystemTime::now()));
40+
let duration = end - start;
41+
42+
human_duration(duration)
43+
}
44+
45+
/// Format a duration using ms/s/m as units depending on how long the
46+
/// duration was
47+
pub fn human_duration(duration: Duration) -> String {
48+
if duration.num_seconds() < 5 {
49+
format!("{}ms", duration.num_milliseconds())
50+
} else if duration.num_minutes() < 5 {
51+
format!("{}s", duration.num_seconds())
52+
} else {
53+
format!("{}m", duration.num_minutes())
54+
}
55+
}
56+
57+
/// Abbreviate a long name to fit into `size` characters. The abbreviation
58+
/// is done by replacing the middle of the name with `..`. For example, if
59+
/// `name` is `foo_bar_baz` and `size` is 10, the result will be
60+
/// `foo.._baz`. If the name is shorter than `size`, it is returned
61+
/// unchanged.
62+
pub fn abbreviate(name: &str, size: usize) -> String {
63+
if name.len() > size {
64+
let fragment = size / 2 - 2;
65+
let last = name.len() - fragment;
66+
let mut name = name.to_string();
67+
name.replace_range(fragment..last, "..");
68+
let table = name.trim().to_string();
69+
table
70+
} else {
71+
name.to_string()
72+
}
73+
}
74+
75+
pub fn date_time(date: &DateTime<Utc>) -> String {
76+
let date = DateTime::<Local>::from(*date);
77+
date.format("%Y-%m-%d %H:%M:%S%Z").to_string()
78+
}

node/src/manager/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pub mod color;
88
pub mod commands;
99
pub mod deployment;
1010
mod display;
11+
pub mod fmt;
1112
pub mod prompt;
1213

1314
/// A dummy subscription manager that always panics

0 commit comments

Comments
 (0)