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.local.nix
|
||||
.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]
|
||||
members = [
|
||||
"autolingual",
|
||||
"autolingual-macro"
|
||||
"endolingual",
|
||||
"endolingual-macro"
|
||||
]
|
||||
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!
|
||||
|
||||
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
|
||||
|
||||
```rs
|
||||
use autolingual::{translate, TranslationSet};
|
||||
use endolingual::{translate, TranslationSet};
|
||||
|
||||
// No context
|
||||
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
|
||||
{
|
||||
# https://devenv.sh/basics/
|
||||
env.GREET = "devenv";
|
||||
|
||||
# https://devenv.sh/packages/
|
||||
dotenv.enable = true;
|
||||
|
||||
packages = [
|
||||
pkgs-unstable.git
|
||||
pkgs-unstable.rustup
|
||||
|
@ -25,7 +25,6 @@ in
|
|||
pkgs-unstable.jq
|
||||
];
|
||||
|
||||
# https://devenv.sh/languages/
|
||||
languages.rust = {
|
||||
channel = "nightly";
|
||||
components = [
|
||||
|
@ -38,6 +37,7 @@ in
|
|||
};
|
||||
|
||||
enterShell = ''
|
||||
rustup default nightly
|
||||
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]
|
||||
name = "autolingual"
|
||||
name = "endolingual"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
description = "Compile-time natural language translations using translation APIs"
|
||||
|
||||
[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