mirror of
https://github.com/moghtech/komodo.git
synced 2026-09-13 08:01:17 +00:00
better sync coloring
This commit is contained in:
@@ -30,6 +30,7 @@ use crate::{
|
||||
resource::{
|
||||
get_updates_for_execution, AllResourcesById, ResourceSync,
|
||||
},
|
||||
Color,
|
||||
},
|
||||
update::update_update,
|
||||
},
|
||||
@@ -205,7 +206,10 @@ impl Resolve<RunSync, (User, Update)> for State {
|
||||
{
|
||||
update.push_simple_log(
|
||||
"No Changes",
|
||||
format!("{}. exiting.", colored("nothing to do", "green")),
|
||||
format!(
|
||||
"{}. exiting.",
|
||||
colored("nothing to do", Color::Green)
|
||||
),
|
||||
);
|
||||
update.finalize();
|
||||
update_update(update.clone()).await?;
|
||||
|
||||
@@ -4,7 +4,7 @@ use anyhow::{anyhow, Context};
|
||||
use monitor_client::entities::{toml::ResourcesToml, update::Log};
|
||||
use serde::de::DeserializeOwned;
|
||||
|
||||
use super::{colored, muted};
|
||||
use super::{colored, muted, Color};
|
||||
|
||||
pub fn read_resources(
|
||||
path: &Path,
|
||||
@@ -42,8 +42,8 @@ fn read_resources_recursive(
|
||||
log.push_str(&format!(
|
||||
"{}: {} from {}",
|
||||
muted("INFO"),
|
||||
colored("adding resources", "green"),
|
||||
colored(&path.display().to_string(), "blue")
|
||||
colored("adding resources", Color::Green),
|
||||
colored(&path.display().to_string(), Color::Blue)
|
||||
));
|
||||
|
||||
resources.servers.extend(more.servers);
|
||||
@@ -68,8 +68,8 @@ fn read_resources_recursive(
|
||||
log.push('\n');
|
||||
log.push_str(&format!(
|
||||
"{}: failed to read additional resources from {} | {e:#}",
|
||||
colored("ERROR", "red"),
|
||||
colored(&path.display().to_string(), "blue")
|
||||
colored("ERROR", Color::Red),
|
||||
colored(&path.display().to_string(), Color::Blue)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,22 @@ fn bold(content: &str) -> String {
|
||||
format!("<span class=\"font-bold\">{content}</span>")
|
||||
}
|
||||
|
||||
pub fn colored(content: &str, color: &str) -> String {
|
||||
format!("<span class=\"text-{color}-500\">{content}</span>")
|
||||
pub fn colored(content: &str, color: Color) -> String {
|
||||
format!("<span class=\"{color}\">{content}</span>")
|
||||
}
|
||||
|
||||
pub enum Color {
|
||||
Red,
|
||||
Green,
|
||||
Blue,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Color {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Color::Red => f.write_str("text-red-700 dark:text-red-400"),
|
||||
Color::Green => f.write_str("text-green-700 dark:text-green-400"),
|
||||
Color::Blue => f.write_str("text-blue-700 dark:text-blue-400"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ use resolver_api::Resolve;
|
||||
|
||||
use crate::{resource::MonitorResource, state::State};
|
||||
|
||||
use super::{bold, colored, muted};
|
||||
use super::{bold, colored, muted, Color};
|
||||
|
||||
pub type ToUpdate<T> = Vec<ToUpdateItem<T>>;
|
||||
pub type ToCreate<T> = Vec<ResourceToml<T>>;
|
||||
@@ -93,7 +93,7 @@ pub trait ResourceSync: MonitorResource + Sized {
|
||||
has_error = true;
|
||||
log.push_str(&format!(
|
||||
"\n{}: failed to create {} '{}' | {e:#}",
|
||||
colored("ERROR", "red"),
|
||||
colored("ERROR", Color::Red),
|
||||
Self::resource_type(),
|
||||
bold(&name)
|
||||
));
|
||||
@@ -119,7 +119,7 @@ pub trait ResourceSync: MonitorResource + Sized {
|
||||
log.push_str(&format!(
|
||||
"\n{}: {} {} '{}'",
|
||||
muted("INFO"),
|
||||
colored("created", "green"),
|
||||
colored("created", Color::Green),
|
||||
Self::resource_type(),
|
||||
bold(&name)
|
||||
));
|
||||
@@ -170,7 +170,7 @@ pub trait ResourceSync: MonitorResource + Sized {
|
||||
has_error = true;
|
||||
log.push_str(&format!(
|
||||
"\n{}: failed to update config on {} '{}' | {e:#}",
|
||||
colored("ERROR", "red"),
|
||||
colored("ERROR", Color::Red),
|
||||
Self::resource_type(),
|
||||
bold(&name),
|
||||
))
|
||||
@@ -178,7 +178,7 @@ pub trait ResourceSync: MonitorResource + Sized {
|
||||
log.push_str(&format!(
|
||||
"\n{}: {} {} '{}' configuration",
|
||||
muted("INFO"),
|
||||
colored("updated", "blue"),
|
||||
colored("updated", Color::Blue),
|
||||
Self::resource_type(),
|
||||
bold(&name)
|
||||
));
|
||||
@@ -193,7 +193,7 @@ pub trait ResourceSync: MonitorResource + Sized {
|
||||
has_error = true;
|
||||
log.push_str(&format!(
|
||||
"\n{}: failed to delete {} '{}' | {e:#}",
|
||||
colored("ERROR", "red"),
|
||||
colored("ERROR", Color::Red),
|
||||
Self::resource_type(),
|
||||
bold(&resource),
|
||||
))
|
||||
@@ -201,7 +201,7 @@ pub trait ResourceSync: MonitorResource + Sized {
|
||||
log.push_str(&format!(
|
||||
"\n{}: {} {} '{}'",
|
||||
muted("INFO"),
|
||||
colored("deleted", "red"),
|
||||
colored("deleted", Color::Red),
|
||||
Self::resource_type(),
|
||||
bold(&resource)
|
||||
));
|
||||
@@ -283,7 +283,7 @@ pub async fn get_updates_for_view<Resource: ResourceSync>(
|
||||
|
||||
update.log.push_str(&format!(
|
||||
"\n\n{}: {}: '{}'\n-------------------",
|
||||
colored("UPDATE", "blue"),
|
||||
colored("UPDATE", Color::Blue),
|
||||
Resource::resource_type(),
|
||||
bold(&resource.name)
|
||||
));
|
||||
@@ -294,14 +294,14 @@ pub async fn get_updates_for_view<Resource: ResourceSync>(
|
||||
"{}: 'description'\n{}: {}\n{}: {}",
|
||||
muted("field"),
|
||||
muted("from"),
|
||||
colored(&original.description, "red"),
|
||||
colored(&original.description, Color::Red),
|
||||
muted("to"),
|
||||
colored(&resource.description, "green")
|
||||
colored(&resource.description, Color::Green)
|
||||
));
|
||||
}
|
||||
if resource.tags != original_tags {
|
||||
let from = colored(&format!("{:?}", original_tags), "red");
|
||||
let to = colored(&format!("{:?}", resource.tags), "green");
|
||||
let from = colored(&format!("{:?}", original_tags), Color::Red);
|
||||
let to = colored(&format!("{:?}", resource.tags), Color::Green);
|
||||
lines.push(format!(
|
||||
"{}: 'tags'\n{}: {from}\n{}: {to}",
|
||||
muted("field"),
|
||||
@@ -315,9 +315,9 @@ pub async fn get_updates_for_view<Resource: ResourceSync>(
|
||||
"{}: '{field}'\n{}: {}\n{}: {}",
|
||||
muted("field"),
|
||||
muted("from"),
|
||||
colored(&from, "red"),
|
||||
colored(&from, Color::Red),
|
||||
muted("to"),
|
||||
colored(&to, "green")
|
||||
colored(&to, Color::Green)
|
||||
)
|
||||
},
|
||||
));
|
||||
@@ -328,7 +328,7 @@ pub async fn get_updates_for_view<Resource: ResourceSync>(
|
||||
update.to_create += 1;
|
||||
update.log.push_str(&format!(
|
||||
"\n\n{}: {}: {}\n{}: {}\n{}: {:?}\n{}: {}",
|
||||
colored("CREATE", "green"),
|
||||
colored("CREATE", Color::Green),
|
||||
Resource::resource_type(),
|
||||
bold(&resource.name),
|
||||
muted("description"),
|
||||
@@ -346,7 +346,7 @@ pub async fn get_updates_for_view<Resource: ResourceSync>(
|
||||
for name in to_delete {
|
||||
update.log.push_str(&format!(
|
||||
"\n\n{}: {}: '{}'\n-------------------",
|
||||
colored("DELETE", "red"),
|
||||
colored("DELETE", Color::Red),
|
||||
Resource::resource_type(),
|
||||
bold(&name)
|
||||
));
|
||||
@@ -459,7 +459,7 @@ pub async fn run_update_tags<Resource: ResourceSync>(
|
||||
*has_error = true;
|
||||
log.push_str(&format!(
|
||||
"\n{}: failed to update tags on {} '{}' | {e:#}",
|
||||
colored("ERROR", "red"),
|
||||
colored("ERROR", Color::Red),
|
||||
Resource::resource_type(),
|
||||
bold(name),
|
||||
))
|
||||
@@ -467,7 +467,7 @@ pub async fn run_update_tags<Resource: ResourceSync>(
|
||||
log.push_str(&format!(
|
||||
"\n{}: {} {} '{}' tags",
|
||||
muted("INFO"),
|
||||
colored("updated", "blue"),
|
||||
colored("updated", Color::Blue),
|
||||
Resource::resource_type(),
|
||||
bold(name)
|
||||
));
|
||||
@@ -494,7 +494,7 @@ pub async fn run_update_description<Resource: ResourceSync>(
|
||||
*has_error = true;
|
||||
log.push_str(&format!(
|
||||
"\n{}: failed to update description on {} '{}' | {e:#}",
|
||||
colored("ERROR", "red"),
|
||||
colored("ERROR", Color::Red),
|
||||
Resource::resource_type(),
|
||||
bold(name),
|
||||
))
|
||||
@@ -502,7 +502,7 @@ pub async fn run_update_description<Resource: ResourceSync>(
|
||||
log.push_str(&format!(
|
||||
"\n{}: {} {} '{}' description",
|
||||
muted("INFO"),
|
||||
colored("updated", "blue"),
|
||||
colored("updated", Color::Blue),
|
||||
Resource::resource_type(),
|
||||
bold(name)
|
||||
));
|
||||
|
||||
@@ -22,7 +22,7 @@ use crate::{
|
||||
resource::{
|
||||
run_update_description, run_update_tags, ResourceSync,
|
||||
ToUpdateItem,
|
||||
},
|
||||
}, Color,
|
||||
},
|
||||
resource::MonitorResource,
|
||||
};
|
||||
@@ -329,7 +329,7 @@ impl ResourceSync for Procedure {
|
||||
has_error = true;
|
||||
log.push_str(&format!(
|
||||
"{}: failed to delete {} '{}' | {e:#}",
|
||||
colored("ERROR", "red"),
|
||||
colored("ERROR", Color::Red),
|
||||
Self::resource_type(),
|
||||
bold(&name),
|
||||
))
|
||||
@@ -337,7 +337,7 @@ impl ResourceSync for Procedure {
|
||||
log.push_str(&format!(
|
||||
"{}: {} {} '{}'",
|
||||
muted("INFO"),
|
||||
colored("deleted", "red"),
|
||||
colored("deleted", Color::Red),
|
||||
Self::resource_type(),
|
||||
bold(&name)
|
||||
));
|
||||
@@ -398,7 +398,7 @@ impl ResourceSync for Procedure {
|
||||
has_error = true;
|
||||
log.push_str(&format!(
|
||||
"\n{}: failed to update {} '{}' | {e:#}",
|
||||
colored("ERROR", "red"),
|
||||
colored("ERROR", Color::Red),
|
||||
Self::resource_type(),
|
||||
bold(&name)
|
||||
));
|
||||
@@ -437,7 +437,7 @@ impl ResourceSync for Procedure {
|
||||
has_error = true;
|
||||
log.push_str(&format!(
|
||||
"\n{}: failed to create {} '{}' | {e:#}",
|
||||
colored("ERROR", "red"),
|
||||
colored("ERROR", Color::Red),
|
||||
Self::resource_type(),
|
||||
bold(&name)
|
||||
));
|
||||
@@ -464,7 +464,7 @@ impl ResourceSync for Procedure {
|
||||
log.push_str(&format!(
|
||||
"\n{}: {} {} '{}'",
|
||||
muted("INFO"),
|
||||
colored("created", "green"),
|
||||
colored("created", Color::Green),
|
||||
Self::resource_type(),
|
||||
bold(&name)
|
||||
));
|
||||
|
||||
@@ -22,7 +22,7 @@ use resolver_api::Resolve;
|
||||
|
||||
use crate::state::{db_client, State};
|
||||
|
||||
use super::{bold, colored, muted, resource::AllResourcesById};
|
||||
use super::{bold, colored, muted, resource::AllResourcesById, Color};
|
||||
|
||||
pub struct UpdateItem {
|
||||
user_group: UserGroupToml,
|
||||
@@ -77,8 +77,8 @@ pub async fn get_updates_for_view(
|
||||
update.to_create += 1;
|
||||
update.log.push_str(&format!(
|
||||
"\n\n{}: user group: {}\n{}: {:?}\n{}: {:?}",
|
||||
colored("CREATE", "green"),
|
||||
colored(&user_group.name, "green"),
|
||||
colored("CREATE", Color::Green),
|
||||
colored(&user_group.name, Color::Green),
|
||||
muted("users"),
|
||||
user_group.users,
|
||||
muted("permissions"),
|
||||
@@ -196,7 +196,7 @@ pub async fn get_updates_for_view(
|
||||
update.to_update += 1;
|
||||
update.log.push_str(&format!(
|
||||
"\n\n{}: user group: '{}'\n-------------------",
|
||||
colored("UPDATE", "blue"),
|
||||
colored("UPDATE", Color::Blue),
|
||||
bold(&user_group.name),
|
||||
));
|
||||
let mut lines = Vec::<String>::new();
|
||||
@@ -210,7 +210,7 @@ pub async fn get_updates_for_view(
|
||||
let adding = if adding.is_empty() {
|
||||
String::from("None")
|
||||
} else {
|
||||
colored(&adding.join(", "), "green")
|
||||
colored(&adding.join(", "), Color::Green)
|
||||
};
|
||||
let removing = original_users
|
||||
.iter()
|
||||
@@ -220,7 +220,7 @@ pub async fn get_updates_for_view(
|
||||
let removing = if removing.is_empty() {
|
||||
String::from("None")
|
||||
} else {
|
||||
colored(&removing.join(", "), "red")
|
||||
colored(&removing.join(", "), Color::Red)
|
||||
};
|
||||
lines.push(format!(
|
||||
"{}: 'users'\n{}: {removing}\n{}: {adding}",
|
||||
@@ -241,7 +241,7 @@ pub async fn get_updates_for_view(
|
||||
let adding = if adding.is_empty() {
|
||||
String::from("None")
|
||||
} else {
|
||||
colored(&adding.join(", "), "green")
|
||||
colored(&adding.join(", "), Color::Green)
|
||||
};
|
||||
let removing = original_permissions
|
||||
.iter()
|
||||
@@ -253,7 +253,7 @@ pub async fn get_updates_for_view(
|
||||
let removing = if removing.is_empty() {
|
||||
String::from("None")
|
||||
} else {
|
||||
colored(&removing.join(", "), "red")
|
||||
colored(&removing.join(", "), Color::Red)
|
||||
};
|
||||
lines.push(format!(
|
||||
"{}: 'permissions'\n{}: {removing}\n{}: {adding}",
|
||||
@@ -270,7 +270,7 @@ pub async fn get_updates_for_view(
|
||||
for name in &to_delete {
|
||||
update.log.push_str(&format!(
|
||||
"\n\n{}: user group: '{}'\n-------------------",
|
||||
colored("DELETE", "red"),
|
||||
colored("DELETE", Color::Red),
|
||||
bold(name),
|
||||
));
|
||||
}
|
||||
@@ -495,7 +495,7 @@ pub async fn run_updates(
|
||||
has_error = true;
|
||||
log.push_str(&format!(
|
||||
"\n{}: failed to create user group '{}' | {e:#}",
|
||||
colored("ERROR", "red"),
|
||||
colored("ERROR", Color::Red),
|
||||
bold(&user_group.name)
|
||||
));
|
||||
continue;
|
||||
@@ -503,7 +503,7 @@ pub async fn run_updates(
|
||||
log.push_str(&format!(
|
||||
"\n{}: {} user group '{}'",
|
||||
muted("INFO"),
|
||||
colored("created", "green"),
|
||||
colored("created", Color::Green),
|
||||
bold(&user_group.name)
|
||||
))
|
||||
};
|
||||
@@ -562,14 +562,14 @@ pub async fn run_updates(
|
||||
has_error = true;
|
||||
log.push_str(&format!(
|
||||
"\n{}: failed to delete user group '{}' | {e:#}",
|
||||
colored("ERROR", "red"),
|
||||
colored("ERROR", Color::Red),
|
||||
bold(&user_group.name)
|
||||
))
|
||||
} else {
|
||||
log.push_str(&format!(
|
||||
"\n{}: {} user group '{}'",
|
||||
muted("INFO"),
|
||||
colored("deleted", "red"),
|
||||
colored("deleted", Color::Red),
|
||||
bold(&user_group.name)
|
||||
))
|
||||
}
|
||||
@@ -602,14 +602,14 @@ async fn set_users(
|
||||
*has_error = true;
|
||||
log.push_str(&format!(
|
||||
"\n{}: failed to set users in group {} | {e:#}",
|
||||
colored("ERROR", "red"),
|
||||
colored("ERROR", Color::Red),
|
||||
bold(&user_group)
|
||||
))
|
||||
} else {
|
||||
log.push_str(&format!(
|
||||
"\n{}: {} user group '{}' users",
|
||||
muted("INFO"),
|
||||
colored("updated", "blue"),
|
||||
colored("updated", Color::Blue),
|
||||
bold(&user_group)
|
||||
))
|
||||
}
|
||||
@@ -636,14 +636,14 @@ async fn run_update_permissions(
|
||||
*has_error = true;
|
||||
log.push_str(&format!(
|
||||
"\n{}: failed to set permssion in group {} | target: {target:?} | {e:#}",
|
||||
colored("ERROR", "red"),
|
||||
colored("ERROR", Color::Red),
|
||||
bold(&user_group)
|
||||
))
|
||||
} else {
|
||||
log.push_str(&format!(
|
||||
"\n{}: {} user group '{}' permissions",
|
||||
muted("INFO"),
|
||||
colored("updated", "blue"),
|
||||
colored("updated", Color::Blue),
|
||||
bold(&user_group)
|
||||
))
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ use resolver_api::Resolve;
|
||||
|
||||
use crate::state::{db_client, State};
|
||||
|
||||
use super::{bold, colored, muted};
|
||||
use super::{bold, colored, muted, Color};
|
||||
|
||||
pub struct ToUpdateItem {
|
||||
pub variable: Variable,
|
||||
@@ -66,7 +66,7 @@ pub async fn get_updates_for_view(
|
||||
update.to_update += 1;
|
||||
update.log.push_str(&format!(
|
||||
"\n\n{}: variable: '{}'\n-------------------",
|
||||
colored("UPDATE", "blue"),
|
||||
colored("UPDATE", Color::Blue),
|
||||
bold(&item.variable.name),
|
||||
));
|
||||
|
||||
@@ -77,9 +77,9 @@ pub async fn get_updates_for_view(
|
||||
"{}: 'value'\n{}: {}\n{}: {}",
|
||||
muted("field"),
|
||||
muted("from"),
|
||||
colored(&original.value, "red"),
|
||||
colored(&original.value, Color::Red),
|
||||
muted("to"),
|
||||
colored(&item.variable.value, "green")
|
||||
colored(&item.variable.value, Color::Green)
|
||||
))
|
||||
}
|
||||
|
||||
@@ -88,9 +88,9 @@ pub async fn get_updates_for_view(
|
||||
"{}: 'description'\n{}: {}\n{}: {}",
|
||||
muted("field"),
|
||||
muted("from"),
|
||||
colored(&original.description, "red"),
|
||||
colored(&original.description, Color::Red),
|
||||
muted("to"),
|
||||
colored(&item.variable.description, "green")
|
||||
colored(&item.variable.description, Color::Green)
|
||||
))
|
||||
}
|
||||
|
||||
@@ -102,16 +102,16 @@ pub async fn get_updates_for_view(
|
||||
if variable.description.is_empty() {
|
||||
update.log.push_str(&format!(
|
||||
"\n\n{}: variable: {}\n{}: {}",
|
||||
colored("CREATE", "green"),
|
||||
colored(&variable.name, "green"),
|
||||
colored("CREATE", Color::Green),
|
||||
colored(&variable.name, Color::Green),
|
||||
muted("value"),
|
||||
variable.value,
|
||||
));
|
||||
} else {
|
||||
update.log.push_str(&format!(
|
||||
"\n\n{}: variable: {}\n{}: {}\n{}: {}",
|
||||
colored("CREATE", "green"),
|
||||
colored(&variable.name, "green"),
|
||||
colored("CREATE", Color::Green),
|
||||
colored(&variable.name, Color::Green),
|
||||
muted("description"),
|
||||
variable.description,
|
||||
muted("value"),
|
||||
@@ -125,7 +125,7 @@ pub async fn get_updates_for_view(
|
||||
for name in &to_delete {
|
||||
update.log.push_str(&format!(
|
||||
"\n\n{}: variable: '{}'\n-------------------",
|
||||
colored("DELETE", "red"),
|
||||
colored("DELETE", Color::Red),
|
||||
bold(name),
|
||||
));
|
||||
}
|
||||
@@ -212,14 +212,14 @@ pub async fn run_updates(
|
||||
has_error = true;
|
||||
log.push_str(&format!(
|
||||
"\n{}: failed to create variable '{}' | {e:#}",
|
||||
colored("ERROR", "red"),
|
||||
colored("ERROR", Color::Red),
|
||||
bold(&variable.name)
|
||||
));
|
||||
} else {
|
||||
log.push_str(&format!(
|
||||
"\n{}: {} variable '{}'",
|
||||
muted("INFO"),
|
||||
colored("created", "green"),
|
||||
colored("created", Color::Green),
|
||||
bold(&variable.name)
|
||||
))
|
||||
};
|
||||
@@ -245,14 +245,14 @@ pub async fn run_updates(
|
||||
has_error = true;
|
||||
log.push_str(&format!(
|
||||
"\n{}: failed to update variable value for '{}' | {e:#}",
|
||||
colored("ERROR", "red"),
|
||||
colored("ERROR", Color::Red),
|
||||
bold(&variable.name)
|
||||
))
|
||||
} else {
|
||||
log.push_str(&format!(
|
||||
"\n{}: {} variable '{}' value",
|
||||
muted("INFO"),
|
||||
colored("updated", "blue"),
|
||||
colored("updated", Color::Blue),
|
||||
bold(&variable.name)
|
||||
))
|
||||
};
|
||||
@@ -271,14 +271,14 @@ pub async fn run_updates(
|
||||
has_error = true;
|
||||
log.push_str(&format!(
|
||||
"\n{}: failed to update variable description for '{}' | {e:#}",
|
||||
colored("ERROR", "red"),
|
||||
colored("ERROR", Color::Red),
|
||||
bold(&variable.name)
|
||||
))
|
||||
} else {
|
||||
log.push_str(&format!(
|
||||
"\n{}: {} variable '{}' description",
|
||||
muted("INFO"),
|
||||
colored("updated", "blue"),
|
||||
colored("updated", Color::Blue),
|
||||
bold(&variable.name)
|
||||
))
|
||||
};
|
||||
@@ -298,14 +298,14 @@ pub async fn run_updates(
|
||||
has_error = true;
|
||||
log.push_str(&format!(
|
||||
"\n{}: failed to delete variable '{}' | {e:#}",
|
||||
colored("ERROR", "red"),
|
||||
colored("ERROR", Color::Red),
|
||||
bold(&variable)
|
||||
))
|
||||
} else {
|
||||
log.push_str(&format!(
|
||||
"\n{}: {} variable '{}'",
|
||||
muted("INFO"),
|
||||
colored("deleted", "red"),
|
||||
colored("deleted", Color::Red),
|
||||
bold(&variable)
|
||||
))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user