Add utils crates

This commit is contained in:
2025-06-04 11:30:22 -03:00
parent f5d3e86eb2
commit 738f9c947b
18 changed files with 412 additions and 1 deletions

View File

@ -22,12 +22,18 @@ exclude = [
"scripts/",
]
[workspace]
resolver = "2"
members = ["src/*"]
exclude = ["src/apis", "src/models"]
[lib]
name = "tribufu"
crate-type = ["rlib"]
path = "src/lib.rs"
[dependencies]
tribufu-constants = { version = "0.0.5", path = "./src/constants" }
async-trait = "^0.1"
reqwest = { version = "^0.12", features = ["json", "multipart"] }
serde = { version = "^1.0", features = ["derive"] }

10
examples/agent.rs Normal file
View File

@ -0,0 +1,10 @@
// Copyright (c) Tribufu. All Rights Reserved.
// SPDX-License-Identifier: MIT
use tribufu::TribufuApi;
#[tokio::main]
async fn main() {
let user_agent = TribufuApi::get_user_agent();
println!("{}", user_agent);
}

20
src/constants/Cargo.toml Normal file
View File

@ -0,0 +1,20 @@
[package]
name = "tribufu-constants"
version = "0.0.5"
description = "Tribufu Constants"
repository = "https://github.com/tribufu/tribufu-rust"
authors = ["Tribufu <contact@tribufu.com>"]
edition = "2021"
publish = false
[lib]
name = "tribufu_constants"
crate-type = ["rlib"]
path = "lib.rs"
[build-dependencies]
vergen = { version = "=5.1.5", default-features = false, features = [
"build",
"cargo",
"rustc",
] }

8
src/constants/build.rs Normal file
View File

@ -0,0 +1,8 @@
// Copyright (c) Tribufu. All Rights Reserved.
// SPDX-License-Identifier: MIT
use vergen::{vergen, Config};
fn main() {
vergen(Config::default()).unwrap();
}

19
src/constants/lib.rs Normal file
View File

@ -0,0 +1,19 @@
// Copyright (c) Tribufu. All Rights Reserved.
// SPDX-License-Identifier: MIT
use std::env::consts;
pub const BUILD_TIMESTAMP: &'static str = env!("VERGEN_BUILD_TIMESTAMP");
pub const CARGO_PROFILE: &'static str = env!("VERGEN_CARGO_PROFILE");
pub const LLVM_VERSION: &'static str = env!("VERGEN_RUSTC_LLVM_VERSION");
pub const RUSTC_CHANNEL: &'static str = env!("VERGEN_RUSTC_CHANNEL");
pub const RUSTC_COMMIT: &'static str = env!("VERGEN_RUSTC_COMMIT_HASH");
pub const RUSTC_VERSION: &'static str = env!("VERGEN_RUSTC_SEMVER");
pub const TARGET_ARCH: &'static str = consts::ARCH;
pub const TARGET_DLL_EXTENSION: &'static str = consts::DLL_EXTENSION;
pub const TARGET_DLL_SUFFIX: &'static str = consts::DLL_SUFFIX;
pub const TARGET_EXE_EXTENSION: &'static str = consts::EXE_EXTENSION;
pub const TARGET_EXE_SUFFIX: &'static str = consts::EXE_SUFFIX;
pub const TARGET_FAMILY: &'static str = consts::FAMILY;
pub const TARGET_OS: &'static str = consts::OS;
pub const TARGET_TRIPLE: &'static str = env!("VERGEN_CARGO_TARGET_TRIPLE");

17
src/error/Cargo.toml Normal file
View File

@ -0,0 +1,17 @@
[package]
name = "tribufu-error"
version = "0.0.5"
description = "Tribufu Error"
repository = "https://github.com/tribufu/tribufu-rust"
authors = ["Tribufu <contact@tribufu.com>"]
edition = "2021"
publish = false
[lib]
name = "tribufu_error"
crate-type = ["rlib"]
path = "lib.rs"
[dependencies]
anyhow = "1.0.44"
thiserror = "2.0.12"

7
src/error/lib.rs Normal file
View File

@ -0,0 +1,7 @@
// Copyright (c) Tribufu. All Rights Reserved.
// SPDX-License-Identifier: MIT
pub use anyhow::Error;
pub use thiserror::Error;
pub type Result<T> = core::result::Result<T, Error>;

18
src/json/Cargo.toml Normal file
View File

@ -0,0 +1,18 @@
[package]
name = "tribufu-json"
version = "0.0.5"
description = "Tribufu Json"
repository = "https://github.com/tribufu/tribufu-rust"
authors = ["Tribufu <contact@tribufu.com>"]
edition = "2021"
publish = false
[lib]
name = "tribufu_json"
crate-type = ["rlib"]
path = "lib.rs"
[dependencies]
tribufu-error = { version = "0.0.5", path = "../error" }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

49
src/json/lib.rs Normal file
View File

@ -0,0 +1,49 @@
// Copyright (c) Tribufu. All Rights Reserved.
// SPDX-License-Identifier: MIT
use serde::Serialize;
use serde_json::ser::PrettyFormatter;
use serde_json::Serializer;
use tribufu_error::Result;
#[macro_export]
macro_rules! include_json {
($path:expr) => {
$crate::from_str(include_str!($path)).expect("Failed to load JSON")
};
}
pub use serde_json::from_slice;
pub use serde_json::from_str;
pub use serde_json::to_string;
pub use serde_json::to_value;
pub use serde_json::to_vec_pretty;
pub fn to_string_pretty<T>(value: &T) -> Result<String>
where
T: Serialize,
{
let obj = to_value(value).expect("Failed to serialize JSON");
let mut buf = Vec::new();
let fmt = PrettyFormatter::with_indent(b" ");
let mut ser = Serializer::with_formatter(&mut buf, fmt);
obj.serialize(&mut ser)?;
Ok(String::from_utf8(buf)?)
}
#[cfg(test)]
mod tests {
use super::*;
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct JsonTest {
version: String,
}
#[test]
fn test_include_json() {
let data: JsonTest = include_json!("test.json");
assert!(data.version == "0.0.0".to_owned())
}
}

3
src/json/test.json Normal file
View File

@ -0,0 +1,3 @@
{
"version": "0.0.0"
}

View File

@ -7,6 +7,7 @@
use crate::apis::configuration::{ApiKey, Configuration};
use crate::apis::tribufu_generated_api::TribufuGeneratedApiClient;
use reqwest::Client;
use tribufu_constants::{RUSTC_VERSION, TARGET_TRIPLE};
use std::env::{self, consts};
use std::sync::Arc;
@ -68,7 +69,7 @@ impl TribufuApi {
/// Gets the user agent string for the Tribufu API client.
pub fn get_user_agent() -> String {
let version = Self::get_version();
format!("Tribufu/{} ({}; {})", version, consts::OS, consts::ARCH)
format!("Tribufu/{} (Rust {}; {})", version, RUSTC_VERSION, TARGET_TRIPLE)
}
/// Checks if debug mode is enabled.

20
src/log/Cargo.toml Normal file
View File

@ -0,0 +1,20 @@
[package]
name = "tribufu-log"
version = "0.0.5"
description = "Tribufu Log"
repository = "https://github.com/tribufu/tribufu-rust"
authors = ["Tribufu <contact@tribufu.com>"]
edition = "2021"
publish = false
[lib]
name = "tribufu_log"
crate-type = ["rlib"]
path = "lib.rs"
[dependencies]
tribufu-error = { version = "0.0.5", path = "../error" }
chrono = "0.4.23"
env_logger = "0.10.1"
log = "0.4"
serde = { version = "1.0", features = ["derive"] }

19
src/log/colors.rs Normal file
View File

@ -0,0 +1,19 @@
// Copyright (c) Tribufu. All Rights Reserved.
// SPDX-License-Identifier: MIT
pub const BLACK: u8 = 0;
pub const RED: u8 = 1;
pub const GREEN: u8 = 2;
pub const YELLOW: u8 = 3;
pub const BLUE: u8 = 4;
pub const MAGENTA: u8 = 5;
pub const CYAN: u8 = 6;
pub const WHITE: u8 = 7;
pub const BRIGHT_BLACK: u8 = 8;
pub const BRIGHT_RED: u8 = 9;
pub const BRIGHT_GREEN: u8 = 10;
pub const BRIGHT_YELLOW: u8 = 11;
pub const BRIGHT_BLUE: u8 = 12;
pub const BRIGHT_MAGENTA: u8 = 13;
pub const BRIGHT_CYAN: u8 = 14;
pub const BRIGHT_WHITE: u8 = 15;

118
src/log/lib.rs Normal file
View File

@ -0,0 +1,118 @@
// Copyright (c) Tribufu. All Rights Reserved.
// SPDX-License-Identifier: MIT
use chrono::prelude::*;
pub use env_logger::fmt::Color;
use env_logger::{Builder, Target};
pub use log::debug;
pub use log::error;
pub use log::info;
pub use log::trace;
pub use log::warn;
use log::Level;
use log::LevelFilter;
use serde::{Deserialize, Serialize};
use std::io::Write;
pub mod colors;
mod log_config;
pub use log_config::*;
pub fn init() {
let logger = Logger::from_env(None);
logger.init();
}
pub fn init_level(level: LogLevel) {
let logger = Logger::new(level.into());
logger.init();
}
#[derive(Default, Debug, Copy, Clone, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum LogLevel {
#[default]
Off,
Error,
Warn,
Info,
Debug,
Trace,
}
impl LogLevel {
pub fn from_str(s: &str) -> Option<Self> {
match s {
"off" => Some(Self::Off),
"error" => Some(Self::Error),
"warn" => Some(Self::Warn),
"info" => Some(Self::Info),
"debug" => Some(Self::Debug),
"trace" => Some(Self::Trace),
_ => None,
}
}
}
impl From<LogLevel> for LevelFilter {
fn from(level: LogLevel) -> Self {
match level {
LogLevel::Off => LevelFilter::Off,
LogLevel::Error => LevelFilter::Error,
LogLevel::Warn => LevelFilter::Warn,
LogLevel::Info => LevelFilter::Info,
LogLevel::Debug => LevelFilter::Debug,
LogLevel::Trace => LevelFilter::Trace,
}
}
}
pub struct Logger {
builder: Builder,
}
impl Logger {
pub fn new(level: LevelFilter) -> Self {
let mut builder = Builder::new();
builder.filter_level(level);
Self { builder }
}
pub fn with_config(config: LogConfig) -> Self {
let mut builder = Builder::new();
builder.filter_level(config.level.into());
Self { builder }
}
pub fn from_env(var: Option<String>) -> Self {
let builder = Builder::from_env(var.unwrap_or("LOG_LEVEL".to_string()));
Self { builder }
}
pub fn init(mut self) {
self.builder
.target(Target::Stdout)
.format(|fmt, record| {
let mut style = fmt.style();
match record.level() {
Level::Error => style.set_color(Color::Ansi256(colors::RED)),
Level::Warn => style.set_color(Color::Ansi256(colors::YELLOW)),
Level::Info => style.set_color(Color::Ansi256(colors::GREEN)),
Level::Debug => style.set_color(Color::Ansi256(colors::WHITE)),
Level::Trace => style.set_color(Color::Ansi256(colors::BRIGHT_BLACK)),
};
let line = format!(
"[{}] [{}]: {}",
Local::now().format("%Y-%m-%dT%H:%M:%S"),
record.level(),
record.args()
);
writeln!(fmt, "{}", style.value(line))
})
.init();
}
}

22
src/log/log_config.rs Normal file
View File

@ -0,0 +1,22 @@
// Copyright (c) Tribufu. All Rights Reserved.
// SPDX-License-Identifier: MIT
use crate::LogLevel;
use serde::{Deserialize, Serialize};
use std::env;
use tribufu_error::Result;
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
pub struct LogConfig {
pub level: LogLevel,
pub file: Option<String>,
}
impl LogConfig {
pub fn from_env() -> Result<Self> {
Ok(Self {
level: LogLevel::from_str(&env::var("LOG_LEVEL")?).unwrap_or_default(),
file: env::var("LOG_FILE").ok(),
})
}
}

20
src/platform/Cargo.toml Normal file
View File

@ -0,0 +1,20 @@
[package]
name = "tribufu-platform"
version = "0.0.5"
description = "Tribufu Platform"
repository = "https://github.com/tribufu/tribufu-rust"
authors = ["Tribufu <contact@tribufu.com>"]
edition = "2021"
publish = false
[lib]
name = "tribufu_platform"
crate-type = ["rlib"]
path = "lib.rs"
[dependencies]
tribufu-error = { version = "0.0.5", path = "../error" }
dunce = "1.0.4"
[target.'cfg(any(target_os = "windows", target_os = "macos", target_os = "linux"))'.dependencies]
dirs = "5.0.1"

4
src/platform/lib.rs Normal file
View File

@ -0,0 +1,4 @@
// Copyright (c) Tribufu. All Rights Reserved.
// SPDX-License-Identifier: MIT
pub mod paths;

50
src/platform/paths.rs Normal file
View File

@ -0,0 +1,50 @@
// Copyright (c) Tribufu. All Rights Reserved.
// SPDX-License-Identifier: MIT
use std::env;
use std::path::PathBuf;
use tribufu_error::Result;
/// Gets the root base directory of the application.
pub fn app_dir() -> Result<PathBuf> {
let mut path = dunce::canonicalize(env::current_exe()?)?; // /bin/platform/app.exe
path.pop(); // /bin
path.pop(); // /
Ok(path)
}
/// Gets the path to the platform-specific binary directory.
pub fn bin_dir() -> Result<PathBuf> {
let base_dir = app_dir()?;
#[cfg(all(target_os = "macos", not(debug_assertions)))]
return Ok(base_dir.join("MacOS"));
#[cfg(not(all(target_os = "macos", not(debug_assertions))))]
Ok(base_dir.join("bin"))
}
/// Gets the path to the configuration directory.
pub fn config_dir() -> Result<PathBuf> {
Ok(app_dir()?.join("config"))
}
/// Gets the path to the assets directory.
pub fn assets_dir() -> Result<PathBuf> {
Ok(app_dir()?.join("assets"))
}
/// Gets the path to the saved data directory.
pub fn saved_dir() -> Result<PathBuf> {
Ok(app_dir()?.join("saved"))
}
/// Gets the path to the cache directory inside `saved`.
pub fn cache_dir() -> Result<PathBuf> {
Ok(saved_dir()?.join("cache"))
}
/// Gets the path to the logs directory inside `saved`.
pub fn logs_dir() -> Result<PathBuf> {
Ok(saved_dir()?.join("logs"))
}