Compare commits
No commits in common. "main" and "v1.1.0" have entirely different histories.
34
.github/README.md
vendored
34
.github/README.md
vendored
@ -38,48 +38,60 @@ To use localizer-rs, you need a directory (eg. `translations`) with your transla
|
||||
|
||||
1. Import the localizer-rs crate:
|
||||
|
||||
```rust,ignore
|
||||
use localizer_rs;
|
||||
```
|
||||
```rust
|
||||
|
||||
use localizer_rs;
|
||||
|
||||
```
|
||||
|
||||
2. Create a new config object:
|
||||
|
||||
```rust,ignore
|
||||
let config = localizer_rs::Config::new("translations", "en");
|
||||
```
|
||||
```rust
|
||||
|
||||
let config = localizer_rs::Config::new("DIRECTORY NAME", "LANGUAGE NAME");
|
||||
|
||||
```
|
||||
|
||||
3. Translate your text:
|
||||
|
||||
```rust,ignore
|
||||
localizer_rs::t!(config, "key", "placeholder" ="value");
|
||||
```
|
||||
```rust
|
||||
|
||||
config.t("key", vec!["placeholder", "value"]);
|
||||
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
With the following `en.json` file.
|
||||
|
||||
```json
|
||||
|
||||
{
|
||||
"error": "{{color.red}}{{bold}}Error:{{end}} Something went wrong: {{details}}."
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
And the following rust code.
|
||||
|
||||
```rust,ignore
|
||||
```rust
|
||||
|
||||
use localizer_rs;
|
||||
|
||||
fn main() {
|
||||
let config: localizer_rs::Config = localizer_rs::Config::new("translations", "en");
|
||||
|
||||
println!("{:}", localizer_rs::t!(config, "error", "details" = "Path not found"));
|
||||
println!("{:}", config.t("error", vec![("details", "Path not found")]));
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
You will get the following output:
|
||||
|
||||
```bash
|
||||
|
||||
Error: Something went wrong: Path not found.
|
||||
|
||||
```
|
||||
|
||||
Where `Error:` is red and bold.
|
||||
|
||||
2
.github/SECURITY.md
vendored
2
.github/SECURITY.md
vendored
@ -6,8 +6,6 @@
|
||||
| -------- | ------------------ |
|
||||
| `v1.0.0` | :white_check_mark: |
|
||||
| `v1.1.0` | :white_check_mark: |
|
||||
| `v1.1.1` | :white_check_mark: |
|
||||
| `v1.2.0` | :white_check_mark: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
|
||||
3
.github/errors.md
vendored
3
.github/errors.md
vendored
@ -1,3 +0,0 @@
|
||||
# errors module
|
||||
|
||||
Module for dealing with errors.
|
||||
14
.github/workflows/codecov_workflow.yml
vendored
14
.github/workflows/codecov_workflow.yml
vendored
@ -1,14 +0,0 @@
|
||||
name: Codecov
|
||||
permissions: read-all
|
||||
|
||||
on:
|
||||
[push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Upload coverage reports to Codecov
|
||||
uses: codecov/codecov-action@v4
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
10
.github/workflows/dependencies.yml
vendored
10
.github/workflows/dependencies.yml
vendored
@ -16,9 +16,9 @@ jobs:
|
||||
matrix:
|
||||
python-version: ["3.8"]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies from txt files
|
||||
@ -28,7 +28,7 @@ jobs:
|
||||
install-rust-dependencies:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install dependencies from Cargo.toml
|
||||
run: cargo update
|
||||
- name: Install dev-dependencies from Cargo.toml
|
||||
@ -39,8 +39,8 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v3
|
||||
if: ${{ github.event_name != 'push' }}
|
||||
- name: Dependency Review
|
||||
if: ${{ github.event_name != 'push' }}
|
||||
uses: actions/dependency-review-action@v4
|
||||
uses: actions/dependency-review-action@v3
|
||||
|
||||
2
.github/workflows/label.yml
vendored
2
.github/workflows/label.yml
vendored
@ -20,6 +20,6 @@ jobs:
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- uses: actions/labeler@v5
|
||||
- uses: actions/labeler@v4
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
||||
2
.github/workflows/megalinter.yml
vendored
2
.github/workflows/megalinter.yml
vendored
@ -26,7 +26,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }}
|
||||
fetch-depth: 0
|
||||
|
||||
2
.github/workflows/rust.yml
vendored
2
.github/workflows/rust.yml
vendored
@ -11,7 +11,7 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v3
|
||||
- name: Build
|
||||
run: cargo build --verbose
|
||||
- name: Run tests
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "localizer-rs"
|
||||
description = "Localizer helps localize (translate) your rust applications using json files."
|
||||
version = "1.2.0"
|
||||
version = "1.1.0"
|
||||
authors = [
|
||||
"ElBe-Plaq <elbe.dev.plaq@gmail.com>"
|
||||
]
|
||||
@ -10,7 +10,7 @@ rust-version = "1.69"
|
||||
documentation = "https://docs.rs/localizer_rs/"
|
||||
readme = ".github/README.md"
|
||||
repository = "https://github.com/ElBe-Development/localizer-rs/"
|
||||
license = "MIT"
|
||||
license-file = "LICENSE.txt"
|
||||
keywords = ["i18n", "L10n", "json", "local", "translation"]
|
||||
categories = [
|
||||
"internationalization",
|
||||
@ -20,4 +20,4 @@ publish = true
|
||||
|
||||
[dependencies]
|
||||
serde = "1.0.188"
|
||||
serde_json = "1.0.107"
|
||||
serde_json = "1.0.106"
|
||||
|
||||
10
codecov.yml
10
codecov.yml
@ -1,10 +0,0 @@
|
||||
coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
target: 50%
|
||||
threshold: 1%
|
||||
|
||||
comment:
|
||||
require_changes: true
|
||||
require_ci_to_pass: false
|
||||
@ -1 +1 @@
|
||||
pre-commit==4.1.0; python_version>='3.8'
|
||||
pre-commit==3.3.2; python_version>='3.8'
|
||||
|
||||
@ -5,16 +5,15 @@ fn main() {
|
||||
|
||||
println!(
|
||||
"{:}",
|
||||
localizer_rs::t!(
|
||||
config,
|
||||
config.t(
|
||||
"error",
|
||||
"details" = "Something went wrong when trying to do stuff"
|
||||
vec![("details", "Something went wrong when trying to do stuff")]
|
||||
)
|
||||
);
|
||||
println!(
|
||||
"{:}",
|
||||
localizer_rs::t!(config, "success", "balance" = "$10", "user" = "John Doe")
|
||||
config.t("success", vec![("balance", "$10"), ("user", "John Doe")])
|
||||
);
|
||||
|
||||
println!("{:}", localizer_rs::t!(config, "all"));
|
||||
println!("{:}", config.t("all", vec![]));
|
||||
}
|
||||
|
||||
3
justfile
3
justfile
@ -10,7 +10,8 @@ build *ARGUMENTS:
|
||||
|
||||
# Removes temporary files
|
||||
clean:
|
||||
cargo clean
|
||||
rm -rf target
|
||||
rm -rf Tools/__pycache__
|
||||
|
||||
# Lints the rust source files
|
||||
lint *ARGUMENTS:
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
#![doc = include_str!("../.github/errors.md")]
|
||||
// localizer-rs errors
|
||||
// Version: 1.1.1
|
||||
// Version: 1.1.0
|
||||
|
||||
// Copyright (c) 2023-present ElBe Development.
|
||||
|
||||
@ -59,39 +58,12 @@ use std::fmt;
|
||||
/// ```
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct Error {
|
||||
/// The errors name.
|
||||
pub name: String,
|
||||
/// The error description.
|
||||
pub description: String,
|
||||
/// The errors exit code.
|
||||
pub exit_code: i32,
|
||||
}
|
||||
|
||||
/// Display implementation for the error object.
|
||||
impl fmt::Display for Error {
|
||||
/// Format implementation for the error object.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// - `self`: The error object.
|
||||
/// - `f`: The [`fmt::Formatter`] to use.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A [`fmt::Result`] containing the formatted error message.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// # use localizer_rs;
|
||||
/// # let error = localizer_rs::errors::Error::new("name", "description", 1);
|
||||
/// println!("{}", error);
|
||||
/// ```
|
||||
///
|
||||
/// # See also
|
||||
///
|
||||
/// - [`fmt::Display`]
|
||||
/// - [`Error`]
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "\x1b[31;1m{}\x1b[0m: {}", self.name, self.description)
|
||||
}
|
||||
|
||||
124
src/lib.rs
124
src/lib.rs
@ -1,6 +1,6 @@
|
||||
#![doc = include_str!("../.github/README.md")]
|
||||
#![doc = ".github/README.md"]
|
||||
// localizer-rs
|
||||
// Version: 1.2.0
|
||||
// Version: 1.1.0
|
||||
|
||||
// Copyright (c) 2023-present ElBe Development.
|
||||
|
||||
@ -37,6 +37,8 @@ use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
use std::path::Path;
|
||||
|
||||
use errors as error_lib;
|
||||
|
||||
use serde_json;
|
||||
|
||||
|
||||
@ -50,8 +52,7 @@ use serde_json;
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// - `path`: The directory containing the translation files.
|
||||
/// The directory is relative to the path the executable was executed from.
|
||||
/// - `path`: The directory containing the translation files. The directory is relative to the path the executable was executed from.
|
||||
/// - `language`: The language to translate to.
|
||||
///
|
||||
/// # Returns
|
||||
@ -69,10 +70,7 @@ use serde_json;
|
||||
/// ```
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct Config {
|
||||
/// The directory containing the translation files. The directory is relative to the path the
|
||||
/// executable was executed from.
|
||||
pub path: String,
|
||||
/// The language to translate to.
|
||||
pub language: String,
|
||||
}
|
||||
|
||||
@ -86,8 +84,7 @@ impl Config {
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// - `path`: The directory containing the translation files.
|
||||
/// The directory is relative to the path the executable was executed from.
|
||||
/// - `path`: The directory containing the translation files. The directory is relative to the path the executable was executed from.
|
||||
/// - `language`: The language to translate to.
|
||||
///
|
||||
/// # Returns
|
||||
@ -125,8 +122,7 @@ impl Config {
|
||||
/// # Parameters
|
||||
///
|
||||
/// - `self`: The config object. This must be mutable.
|
||||
/// - `str_path`: The directory containing the translation files.
|
||||
/// The directory is relative to the path the executable was executed from.
|
||||
/// - `str_path`: The directory containing the translation files. The directory is relative to the path the executable was executed from.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
@ -153,13 +149,14 @@ impl Config {
|
||||
match path.try_exists() {
|
||||
Ok(value) => {
|
||||
if !value {
|
||||
let error: errors::Error =
|
||||
errors::Error::new("OS Error", "Translation path was not found", 1);
|
||||
let error: error_lib::Error =
|
||||
error_lib::Error::new("OS Error", "Translation path was not found", 1);
|
||||
error.raise(format!("Path: {:?}", str_path).as_str());
|
||||
}
|
||||
}
|
||||
Err(_error) => {
|
||||
let error: errors::Error = errors::Error::new("OS Error", "Could not open path", 2);
|
||||
let error: error_lib::Error =
|
||||
error_lib::Error::new("OS Error", "Could not open path", 2);
|
||||
error.raise(format!("Path: {:?}\nDetails: {}", str_path, _error).as_str());
|
||||
}
|
||||
}
|
||||
@ -167,8 +164,8 @@ impl Config {
|
||||
self.path = String::from(match path.to_owned().to_str() {
|
||||
Some(value) => value,
|
||||
None => {
|
||||
let error: errors::Error =
|
||||
errors::Error::new("OS Error", "Path does not seem to be valid", 3);
|
||||
let error: error_lib::Error =
|
||||
error_lib::Error::new("OS Error", "Path does not seem to be valid", 3);
|
||||
error.raise(format!("Path: {:?}", str_path).as_str());
|
||||
""
|
||||
}
|
||||
@ -225,49 +222,15 @@ impl Config {
|
||||
///
|
||||
/// # See also
|
||||
///
|
||||
/// - [`t!()`]
|
||||
/// - [`Config`]
|
||||
pub fn t(&self, key: &str, arguments: Vec<(&str, &str)>) -> String {
|
||||
return self.translate(key, arguments);
|
||||
return self.translate::<serde_json::Value>(key, arguments);
|
||||
}
|
||||
|
||||
/// Translates the specified key in the language specified in the config.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// - `self`: The config object.
|
||||
/// - `key`: The key to translate to.
|
||||
/// - `arguments`: The arguments to replace.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A `String` containing the translated value.
|
||||
///
|
||||
/// # Raises
|
||||
///
|
||||
/// This method throws an exception and exits if
|
||||
///
|
||||
/// - The translation file could not be found
|
||||
/// - The translation file could not be opened
|
||||
/// - The translation file could not be parsed
|
||||
/// - The parsed json could not be converted to a json value
|
||||
/// - The converted json could not be indexed
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// # use localizer_rs;
|
||||
/// # let config: localizer_rs::Config = localizer_rs::Config::new("examples/translations", "en");
|
||||
/// config.translate("test", vec![]);
|
||||
/// ```
|
||||
///
|
||||
/// # See also
|
||||
///
|
||||
/// - [`t!()`]
|
||||
/// - [`Config`]
|
||||
/// - [`Config::t()`]
|
||||
/// - [`serde_json`]
|
||||
pub fn translate(&self, key: &str, mut arguments: Vec<(&str, &str)>) -> String {
|
||||
fn translate<T>(&self, key: &str, mut arguments: Vec<(&str, &str)>) -> String
|
||||
where
|
||||
T: serde::Serialize + for<'de> serde::Deserialize<'de>,
|
||||
{
|
||||
let mut colors: Vec<(&str, &str)> = vec![
|
||||
// Formatting codes
|
||||
("end", "\x1b[0m"),
|
||||
@ -338,8 +301,8 @@ impl Config {
|
||||
};
|
||||
let reader: BufReader<File> = BufReader::new(file);
|
||||
|
||||
let json: serde_json::Value = match serde_json::to_value::<serde_json::Value>(
|
||||
match serde_json::from_reader::<BufReader<File>, serde_json::Value>(reader) {
|
||||
let json: serde_json::Value = match serde_json::to_value::<T>(
|
||||
match serde_json::from_reader::<BufReader<File>, T>(reader) {
|
||||
Ok(value) => value,
|
||||
Err(_error) => {
|
||||
let error: errors::Error = errors::Error::new(
|
||||
@ -399,50 +362,3 @@ impl Config {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Translates the specified key in the language specified in the config.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// - `config`: The config object.
|
||||
/// - `key`: The key to translate to.
|
||||
/// - `arguments`: Optional parameter. The arguments to replace. Has to be of type `"name" = "value"`.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A `String` containing the translated value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// # use localizer_rs;
|
||||
/// # let config: localizer_rs::Config = localizer_rs::Config::new("examples/translations", "en");
|
||||
/// localizer_rs::t!(config, "test");
|
||||
/// localizer_rs::t!(config, "test", "variable" = "content");
|
||||
/// ```
|
||||
///
|
||||
/// # See also
|
||||
///
|
||||
/// - [`Config`]
|
||||
/// - [`Config::t()`]
|
||||
#[macro_export]
|
||||
macro_rules! t {
|
||||
($config:expr, $key:expr) => {
|
||||
{
|
||||
$config.t($key, vec![])
|
||||
}
|
||||
};
|
||||
|
||||
($config:expr, $key:expr, $($argument_name:literal = $argument_value:literal),* $(,)?) => {
|
||||
{
|
||||
let mut arguments: Vec<(&str, &str)> = vec![];
|
||||
|
||||
$(
|
||||
arguments.push(($argument_name, $argument_value));
|
||||
)*
|
||||
|
||||
$config.t($key, arguments)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// localizer-rs error tests
|
||||
// Version: 1.1.1
|
||||
// Version: 1.1.0
|
||||
|
||||
// Copyright (c) 2023-present ElBe Development.
|
||||
|
||||
|
||||
26
tests/lib.rs
26
tests/lib.rs
@ -1,5 +1,5 @@
|
||||
// localizer-rs tests
|
||||
// Version: 1.2.0
|
||||
// Version: 1.1.0
|
||||
|
||||
// Copyright (c) 2023-present ElBe Development.
|
||||
|
||||
@ -80,18 +80,6 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_translate() {
|
||||
let config: localizer_rs::Config = localizer_rs::Config::new("examples/translations", "en");
|
||||
let translation: String =
|
||||
config.translate("error", vec![("details", "Something went wrong")]);
|
||||
|
||||
assert_eq!(
|
||||
translation.as_str(),
|
||||
"\x1b[31m\x1b[1mError:\x1b[0m Something went wrong"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_translate_t() {
|
||||
let config: localizer_rs::Config = localizer_rs::Config::new("examples/translations", "en");
|
||||
let translation: String = config.t("error", vec![("details", "Something went wrong")]);
|
||||
|
||||
@ -100,16 +88,4 @@ mod tests {
|
||||
"\x1b[31m\x1b[1mError:\x1b[0m Something went wrong"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_translate_macro() {
|
||||
let config: localizer_rs::Config = localizer_rs::Config::new("examples/translations", "en");
|
||||
let translation: String =
|
||||
localizer_rs::t!(config, "error", "details" = "Something went wrong");
|
||||
|
||||
assert_eq!(
|
||||
translation.as_str(),
|
||||
"\x1b[31m\x1b[1mError:\x1b[0m Something went wrong"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user