Basic API request to DeepL
This commit is contained in:
parent
3a9f283e99
commit
d2892b1f82
12 changed files with 1401 additions and 70 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,3 +2,4 @@
|
||||||
.devenv*
|
.devenv*
|
||||||
devenv.local.nix
|
devenv.local.nix
|
||||||
.pre-commit-config.yaml
|
.pre-commit-config.yaml
|
||||||
|
.env
|
||||||
|
|
1306
Cargo.lock
generated
1306
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"autolingual",
|
"endolingual",
|
||||||
"autolingual-macro"
|
"endolingual-macro"
|
||||||
]
|
]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
23
README.md
23
README.md
|
@ -1,25 +1,22 @@
|
||||||
# Autolingual
|
# Endolingual
|
||||||
|
|
||||||
Procedural macros in Rust can execute arbitrary code at compile time, even performing network requests. This has potentially terrifying security implications, but we'll use it to our advantage!
|
Procedural macros in Rust can execute arbitrary code at compile time, even performing network requests. This has potentially terrifying security implications, but we'll use it to our advantage!
|
||||||
|
|
||||||
Autolingual is a Rust macro which automatically translates strings of natural language text into multiple foreign languages at once at compile time. The produced translations are `&'static str` values, so they are very lightweight.
|
Endolingual is a Rust macro which translates strings of natural language text into multiple foreign languages at once by making API requests at compile time. The produced translations are `&'static str` values, so they are very lightweight.
|
||||||
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
```rs
|
```rs
|
||||||
use autolingual::{translate, TranslationSet};
|
use endolingual::{translate, TranslationSet};
|
||||||
|
|
||||||
// No context
|
|
||||||
let button_text_french: &str = translate!("Sign up").fr;
|
let button_text_french: &str = translate!("Sign up").fr;
|
||||||
|
|
||||||
// With context (context will not show up in the final translation)
|
|
||||||
let button_text_french: &str = translate!("Sign up", "A button for creating a user account.").fr;
|
|
||||||
|
|
||||||
// Every supported language at once.
|
|
||||||
let translation_set: TranslationSet = translate!("Hello!");
|
|
||||||
let french = translation_set.fr;
|
|
||||||
let german = translation_set.de;
|
|
||||||
let portuguese = translation_set.pt;
|
|
||||||
// ...
|
// ...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Set the environment variable `DEEPL_API_KEY` to your [DeepL API](https://developers.deepl.com/docs) key. Only DeepL is supported at the moment.
|
||||||
|
|
||||||
|
This library is still experimental and in the early stages of development.
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "autolingual-macro"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
license = "MIT"
|
|
||||||
description = "Procedural macros for autolingual"
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
proc-macro = true
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
proc-macro2 = "1.0"
|
|
||||||
quote = "1.0"
|
|
||||||
syn = { version = "2.0", features = ["full"] }
|
|
|
@ -1,18 +0,0 @@
|
||||||
use proc_macro::TokenStream;
|
|
||||||
use quote::quote;
|
|
||||||
use syn::{parse_macro_input, LitStr};
|
|
||||||
|
|
||||||
#[proc_macro]
|
|
||||||
pub fn translate(input: TokenStream) -> TokenStream {
|
|
||||||
let input = parse_macro_input!(input as LitStr);
|
|
||||||
let text = input.value();
|
|
||||||
|
|
||||||
// TODO: Implement actual translation logic
|
|
||||||
|
|
||||||
quote! {
|
|
||||||
::autolingual::TranslationSet {
|
|
||||||
en: #text,
|
|
||||||
fr: "TODO",
|
|
||||||
}
|
|
||||||
}.into()
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
pub use autolingual_macro::translate;
|
|
||||||
|
|
||||||
pub struct Language {
|
|
||||||
pub code: &'static str,
|
|
||||||
pub name: &'static str,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct TranslationSet {
|
|
||||||
pub en: &'static str,
|
|
||||||
pub fr: &'static str,
|
|
||||||
}
|
|
|
@ -13,10 +13,10 @@ let
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
# https://devenv.sh/basics/
|
|
||||||
env.GREET = "devenv";
|
env.GREET = "devenv";
|
||||||
|
|
||||||
# https://devenv.sh/packages/
|
dotenv.enable = true;
|
||||||
|
|
||||||
packages = [
|
packages = [
|
||||||
pkgs-unstable.git
|
pkgs-unstable.git
|
||||||
pkgs-unstable.rustup
|
pkgs-unstable.rustup
|
||||||
|
@ -25,7 +25,6 @@ in
|
||||||
pkgs-unstable.jq
|
pkgs-unstable.jq
|
||||||
];
|
];
|
||||||
|
|
||||||
# https://devenv.sh/languages/
|
|
||||||
languages.rust = {
|
languages.rust = {
|
||||||
channel = "nightly";
|
channel = "nightly";
|
||||||
components = [
|
components = [
|
||||||
|
@ -38,6 +37,7 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
enterShell = ''
|
enterShell = ''
|
||||||
|
rustup default nightly
|
||||||
rustup component add clippy
|
rustup component add clippy
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
|
19
endolingual-macro/Cargo.toml
Normal file
19
endolingual-macro/Cargo.toml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
[package]
|
||||||
|
name = "endolingual-macro"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
license = "MIT"
|
||||||
|
description = "Procedural macros for endolingual"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
proc-macro = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
proc-macro2 = "1.0"
|
||||||
|
quote = "1.0"
|
||||||
|
syn = { version = "2.0", features = ["full"] }
|
||||||
|
reqwest = { version = "0.12.9", features = ["blocking", "json", "rustls-tls"], default-features = false }
|
||||||
|
serde_json = "1.0"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
endolingual = { path = "../endolingual", version = "0.1.0" }
|
40
endolingual-macro/src/lib.rs
Normal file
40
endolingual-macro/src/lib.rs
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
use proc_macro::TokenStream;
|
||||||
|
use quote::quote;
|
||||||
|
use syn::{parse_macro_input, LitStr};
|
||||||
|
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn translate(input: TokenStream) -> TokenStream {
|
||||||
|
let input = parse_macro_input!(input as LitStr);
|
||||||
|
let text = input.value();
|
||||||
|
|
||||||
|
let api_key =
|
||||||
|
std::env::var("DEEPL_API_KEY").expect("Environment variable `DEEPL_API_KEY` must be set");
|
||||||
|
|
||||||
|
let client = reqwest::blocking::Client::new();
|
||||||
|
let response = client
|
||||||
|
.post("https://api.deepl.com/v2/translate")
|
||||||
|
.header("Authorization", format!("DeepL-Auth-Key {}", api_key))
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.json(&serde_json::json!({
|
||||||
|
"text": [text],
|
||||||
|
"target_lang": "FR"
|
||||||
|
}))
|
||||||
|
.send()
|
||||||
|
.expect("Failed to send request to DeepL API");
|
||||||
|
|
||||||
|
let translation = response
|
||||||
|
.json::<serde_json::Value>()
|
||||||
|
.expect("Failed to parse DeepL API response");
|
||||||
|
|
||||||
|
let translated_text = translation["translations"][0]["text"]
|
||||||
|
.as_str()
|
||||||
|
.expect("Failed to extract translated text");
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
TranslationSet {
|
||||||
|
en: #text,
|
||||||
|
fr: #translated_text,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.into()
|
||||||
|
}
|
|
@ -1,9 +1,9 @@
|
||||||
[package]
|
[package]
|
||||||
name = "autolingual"
|
name = "endolingual"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "Compile-time natural language translations using translation APIs"
|
description = "Compile-time natural language translations using translation APIs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
autolingual-macro = { path = "../autolingual-macro", version = "0.1.0" }
|
endolingual-macro = { path = "../endolingual-macro", version = "0.1.0" }
|
24
endolingual/src/lib.rs
Normal file
24
endolingual/src/lib.rs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
pub use endolingual_macro::translate;
|
||||||
|
|
||||||
|
pub struct Language {
|
||||||
|
pub code: &'static str,
|
||||||
|
pub name: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct TranslationSet {
|
||||||
|
pub en: &'static str,
|
||||||
|
pub fr: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_translate() {
|
||||||
|
let translations = translate!("Hello");
|
||||||
|
let french: &'static str = translations.fr;
|
||||||
|
assert_eq!(french, "Bonjour");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue