Skip to content

Commit 41c9af7

Browse files
committed
can now be used as separated module
1 parent 8e304c1 commit 41c9af7

File tree

22 files changed

+243
-220
lines changed

22 files changed

+243
-220
lines changed

.idea/tl.iml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.lock

Lines changed: 10 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ members = [
44
"tl-types",
55
"tl-parser",
66
"tl-generator",
7+
"tl-example",
78
]

README.md

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -75,17 +75,17 @@ impl crate::Deserialize for Error {
7575

7676
#[derive(Debug, Clone, PartialEq)]
7777
pub enum Function {
78-
GetUsers(crate::functions::GetUsers),
79-
SendMessage(crate::functions::SendMessage),
78+
GetUsers(self::functions::GetUsers),
79+
SendMessage(self::functions::SendMessage),
8080
}
8181

8282
impl crate::Deserialize for Function {
8383
fn deserialize(reader: &mut crate::Reader) -> Result<Self, crate::deserialize::Error> {
8484
let id = u32::deserialize(reader)?;
8585

8686
Ok(match id {
87-
1904452899_u32 => Self::GetUsers(crate::functions::GetUsers::deserialize(reader)?),
88-
339054040_u32 => Self::SendMessage(crate::functions::SendMessage::deserialize(reader)?),
87+
1904452899_u32 => Self::GetUsers(self::functions::GetUsers::deserialize(reader)?),
88+
339054040_u32 => Self::SendMessage(self::functions::SendMessage::deserialize(reader)?),
8989
_ => return Err(crate::deserialize::Error::UnexpectedDefinitionId(id)),
9090
})
9191
}
@@ -209,7 +209,7 @@ pub mod functions {
209209
}
210210

211211
impl crate::Call for GetUsers {
212-
type Return = Vec::<crate::types::User>;
212+
type Return = Vec::<super::types::User>;
213213
}
214214

215215
#[derive(Debug, Clone, PartialEq)]
@@ -239,7 +239,7 @@ pub mod functions {
239239
}
240240

241241
impl crate::Call for SendMessage {
242-
type Return = crate::types::Message;
242+
type Return = super::types::Message;
243243
}
244244

245245
}
@@ -248,8 +248,9 @@ pub mod functions {
248248

249249
### How to use
250250

251-
1. Clone project.
252-
2. Create `schema.tl` file at the root of `tl-types` crate.
253-
3. Specify `tl-types` crate in dependencies of your project.
254-
255-
See `example.rs` in `tl-types/tests` folder.
251+
1. Clone template `tl-example` package.
252+
2. Create schemas in `schemas` folder.
253+
3. Create corresponding modules in `src/schemas` module.
254+
4. Specify schemas in `build.rs`.
255+
5. Remove `src/main.rs` / Edit `Cargo.toml` / Rename package.
256+
6. Specify crate in dependencies of your project.

tl-example/Cargo.toml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[package]
2+
name = "tl-example"
3+
version = "0.1.0"
4+
edition = "2024"
5+
description = "TL example"
6+
license = "MIT"
7+
repository = "https://github.com/lifr0m/tl"
8+
9+
[dependencies]
10+
tl-types = { path = "../tl-types" }
11+
12+
[build-dependencies]
13+
tl-parser = { path = "../tl-parser" }
14+
tl-generator = { path = "../tl-generator" }
15+
anyhow = "1"

tl-example/build.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
use anyhow::Context;
2+
use std::path::PathBuf;
3+
use std::{env, fs};
4+
5+
fn main() -> anyhow::Result<()> {
6+
let out_dir = PathBuf::from(env::var("OUT_DIR")?);
7+
8+
let name_list = ["api"];
9+
let out_dir = out_dir.join("schemas");
10+
11+
if !out_dir.exists() {
12+
fs::create_dir(&out_dir)?;
13+
}
14+
15+
for name in name_list {
16+
let out_file = out_dir.join(format!("{name}.rs"));
17+
18+
let schema = fs::read_to_string(format!("schemas/{name}.tl"))
19+
.with_context(|| format!("failed to read schema: {name}"))?;
20+
let schema = tl_parser::parse_schema(&schema)
21+
.with_context(|| format!("failed to parse schema: {name}"))?;
22+
let code = tl_generator::generate(&schema);
23+
24+
fs::write(out_file, code)
25+
.with_context(|| format!("failed to write generated code for schema: {name}"))?;
26+
}
27+
28+
Ok(())
29+
}

tl-example/schemas/api.tl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
type Message id:int32 text:string? photos:[bytes] sent_at:time = Message
2+
type User id:int64 verified:bool rating:float = User
3+
type UserEmpty id:int64 = User
4+
5+
error InvalidUserId user_id:int64
6+
error TooLongText text:string max_length:int32
7+
8+
func get_users user_ids:[int64] = [User]
9+
func send_message user_id:int64 text:string? photos:[bytes] = Message

tl-example/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
mod schemas;
2+
3+
pub use schemas::*;
4+
pub use tl_types::*;

tl-example/src/main.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
use tl::{Deserialize, Serialize};
2+
use tl_example as tl;
3+
4+
// Located on server side.
5+
mod functions {
6+
use tl_example as tl;
7+
8+
pub fn get_users(func: tl::api::functions::GetUsers) -> Result<<tl::api::functions::GetUsers as tl::Call>::Return, tl::api::Error> {
9+
if func.user_ids.contains(&666) {
10+
Err(tl::api::Error::InvalidUserId {
11+
user_id: 666,
12+
})
13+
} else {
14+
Ok(Vec::from_iter(
15+
func.user_ids.iter()
16+
.map(|&user_id| tl::api::types::User::User {
17+
id: user_id,
18+
verified: true,
19+
rating: 0.74,
20+
})
21+
))
22+
}
23+
}
24+
}
25+
26+
// Located on client side.
27+
fn call<F: Serialize + tl::Call>(func: &F) -> Result<Result<F::Return, tl::api::Error>, tl::deserialize::Error> {
28+
let request = func.to_bytes();
29+
30+
let response = respond(&request)?;
31+
32+
Result::<F::Return, tl::api::Error>::from_bytes(&response)
33+
}
34+
35+
// Located on server side.
36+
fn respond(request: &[u8]) -> Result<Vec<u8>, tl::deserialize::Error> {
37+
let func = tl::api::Function::from_bytes(request)?;
38+
39+
Ok(match func {
40+
tl::api::Function::GetUsers(func) => functions::get_users(func).to_bytes(),
41+
_ => unreachable!(),
42+
})
43+
}
44+
45+
fn main() {}
46+
47+
#[cfg(test)]
48+
mod tests {
49+
use super::*;
50+
51+
#[test]
52+
fn it_works() -> Result<(), tl::deserialize::Error> {
53+
assert_eq!(
54+
call(&tl::api::functions::GetUsers {
55+
user_ids: vec![1],
56+
})?,
57+
Ok(vec![tl::api::types::User::User {
58+
id: 1,
59+
verified: true,
60+
rating: 0.74
61+
}])
62+
);
63+
64+
assert_eq!(
65+
call(&tl::api::functions::GetUsers {
66+
user_ids: vec![666],
67+
})?,
68+
Err(tl::api::Error::InvalidUserId {
69+
user_id: 666,
70+
})
71+
);
72+
73+
Ok(())
74+
}
75+
}

tl-example/src/schemas.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod api;

0 commit comments

Comments
 (0)