Implement in-tree codegen

This commit is contained in:
Maybe Waffle 2022-08-09 21:07:18 +04:00
parent 44d4603bd0
commit b8dc2c7b31
110 changed files with 5318 additions and 836 deletions

View file

@ -24,6 +24,8 @@ env:
# - down below in a matrix
rust_msrv: 1.58.0
CI: 1
jobs:
# Depends on all action that are required for a "successful" CI run.
ci-pass:

View file

@ -2,7 +2,7 @@
name = "teloxide-core"
description = "Core part of the `teloxide` library - telegram bot API client"
version = "0.7.1"
edition = "2018"
edition = "2021"
license = "MIT"
repository = "https://github.com/teloxide/teloxide-core/"
@ -54,6 +54,12 @@ pretty_env_logger = "0.4"
tokio = { version = "1.8.0", features = ["fs", "macros", "macros", "rt-multi-thread"] }
cool_asserts = "2.0.3"
xshell = "0.2"
ron = "0.7"
indexmap = { version = "1.9", features = ["serde-1"] }
aho-corasick = "0.7"
itertools = "0.10"
[features]
default = ["native-tls"]

3849
schema.ron Normal file

File diff suppressed because it is too large Load diff

193
src/codegen.rs Normal file
View file

@ -0,0 +1,193 @@
//! `teloxide-core` uses codegen in order to implement request payloads and
//! `Requester` trait.
//!
//! These are utilities for doing codegen inspired by/stolen from r-a's
//! [sourcegen].
//!
//! [sourcegen]: https://github.com/rust-lang/rust-analyzer/blob/master/crates/sourcegen
// TODO(waffle): does it make sense to extract these utilities (at least project
// agnostic ones) in a standalone crate?
pub(crate) mod convert;
mod patch;
pub(crate) mod schema;
use std::{
fs,
path::{Path, PathBuf},
};
use aho_corasick::AhoCorasick;
use xshell::{cmd, Shell};
fn ensure_rustfmt(sh: &Shell) {
// FIXME(waffle): find a better way to set toolchain
let toolchain = "nightly-2022-01-17";
let version = cmd!(sh, "rustup run {toolchain} rustfmt --version")
.read()
.unwrap_or_default();
if !version.contains("nightly") {
panic!(
"Failed to run rustfmt from toolchain '{toolchain}'. Please run `rustup component add \
rustfmt --toolchain {toolchain}` to install it.",
);
}
}
pub fn reformat(text: String) -> String {
let toolchain = "nightly-2022-01-17";
let sh = Shell::new().unwrap();
ensure_rustfmt(&sh);
let rustfmt_toml = project_root().join("rustfmt.toml");
let mut stdout = cmd!(
sh,
"rustup run {toolchain} rustfmt --config-path {rustfmt_toml} --config fn_single_line=true"
)
.stdin(text)
.read()
.unwrap();
if !stdout.ends_with('\n') {
stdout.push('\n');
}
stdout
}
pub fn add_hidden_preamble(generator: &'static str, mut text: String) -> String {
let preamble = format!("// Generated by `{generator}`, do not edit by hand.\n\n");
text.insert_str(0, &preamble);
text
}
pub fn add_preamble(generator: &'static str, mut text: String) -> String {
let preamble = format!("//! Generated by `{generator}`, do not edit by hand.\n\n");
text.insert_str(0, &preamble);
text
}
/// Checks that the `file` has the specified `contents`. If that is not the
/// case, updates the file and then fails the test.
pub fn ensure_file_contents(file: &Path, contents: &str) {
ensure_files_contents([(file, contents)])
}
pub fn ensure_files_contents<'a>(
files_and_contents: impl IntoIterator<Item = (&'a Path, &'a str)>,
) {
let mut err_count = 0;
for (file, contents) in files_and_contents {
if let Ok(old_contents) = fs::read_to_string(file) {
if normalize_newlines(&old_contents) == normalize_newlines(contents) {
// File is already up to date.
continue;
}
err_count += 1;
let display_path = file.strip_prefix(&project_root()).unwrap_or(file);
eprintln!(
"\n\x1b[31;1merror\x1b[0m: {} was not up-to-date, updating\n",
display_path.display()
);
if let Some(parent) = file.parent() {
let _ = fs::create_dir_all(parent);
}
fs::write(file, contents).unwrap();
}
}
let (s, were) = match err_count {
// No erros, everything is up to date
0 => return,
// Singular
1 => ("", "was"),
// Plural
_ => ("s", "were"),
};
if std::env::var("CI").is_ok() {
eprintln!(" NOTE: run `cargo test` locally and commit the updated files\n");
}
panic!("some file{s} {were} not up to date and has been updated, simply re-run the tests");
}
pub fn replace_block(path: &Path, title: &str, new: &str) -> String {
let file = fs::read_to_string(path).unwrap();
let start = format!("// START BLOCK {title}\n");
let end = format!("// END BLOCK {title}\n");
let mut starts = vec![];
let mut ends = vec![];
let searcher = AhoCorasick::new_auto_configured(&[start, end]);
for finding in searcher.find_iter(&file) {
match finding.pattern() {
// start
0 => starts.push(finding.start()..finding.end()),
// end
1 => ends.push(finding.start()..finding.end()),
n => panic!("{n}"),
}
}
let start_offset = match &*starts {
[] => panic!(
"Coulnd't find start of block {title} in {p}",
p = path.display()
),
[offset] => offset.end,
[..] => panic!(),
};
let end_offset = match &*ends {
[] => panic!(
"Coulnd't find end of block {title} in {p}",
p = path.display()
),
[offset] => offset.start,
[..] => panic!(),
};
if end_offset < start_offset {
panic!(
"End of the {title} block is located before the start in {p}",
p = path.display()
);
}
format!("{}{}{}", &file[..start_offset], new, &file[end_offset..])
}
fn normalize_newlines(s: &str) -> String {
s.replace("\r\n", "\n")
}
/// Changes the first character in a string to uppercase.
pub fn to_uppercase(s: &str) -> String {
let mut chars = s.chars();
format!("{}{}", chars.next().unwrap().to_uppercase(), chars.as_str())
}
pub fn project_root() -> PathBuf {
let dir = env!("CARGO_MANIFEST_DIR");
let res = PathBuf::from(dir);
assert!(res.join("CHANGELOG.md").exists());
res
}
/// Returns minimal prefix of `l` such that `r` doesn't start with the prefix.
#[track_caller]
pub fn min_prefix<'a>(l: &'a str, r: &str) -> &'a str {
l.char_indices()
.zip(r.chars())
.find(|((_, l), r)| l != r)
.map(|((i, _), _)| &l[..=i])
.unwrap_or_else(|| panic!("there is no different prefix for {l} and {r}"))
}

32
src/codegen/convert.rs Normal file
View file

@ -0,0 +1,32 @@
use crate::codegen::schema::Type;
pub enum Convert {
Id(Type),
Into(Type),
Collect(Type),
}
pub fn convert_for(ty: &Type) -> Convert {
match ty {
ty @ Type::True
| ty @ Type::u8
| ty @ Type::u16
| ty @ Type::u32
| ty @ Type::i32
| ty @ Type::u64
| ty @ Type::i64
| ty @ Type::f64
| ty @ Type::bool => Convert::Id(ty.clone()),
ty @ Type::String => Convert::Into(ty.clone()),
Type::Option(inner) => convert_for(inner),
Type::ArrayOf(ty) => Convert::Collect((**ty).clone()),
Type::RawTy(s) => match s.as_str() {
raw @ "Recipient" | raw @ "ChatId" | raw @ "TargetMessage" | raw @ "ReplyMarkup" => {
Convert::Into(Type::RawTy(raw.to_owned()))
}
raw => Convert::Id(Type::RawTy(raw.to_owned())),
},
ty @ Type::Url => Convert::Id(ty.clone()),
ty @ Type::DateTime => Convert::Into(ty.clone()),
}
}

347
src/codegen/patch.rs Normal file
View file

@ -0,0 +1,347 @@
use crate::codegen::schema::{Doc, Schema, Type};
pub fn patch_schema(mut schema: Schema) -> Schema {
fn check(l: &Option<&str>, r: &str) -> bool {
l.map(|m| r == m).unwrap_or(true)
}
schema.methods.iter_mut().for_each(|method| {
method
.params
.iter_mut()
.map(|p| &mut p.name)
.for_each(escape_kw);
DOC_PATCHES.iter().for_each(|(key, patch)| match key {
Target::Method(m) => {
if check(m, &method.names.0) {
method.doc.patch(patch, *key);
}
}
Target::Field {
method_name: m,
field_name: f,
} => {
if check(m, &method.names.0) {
method
.params
.iter_mut()
.filter(|p| check(f, &p.name))
.for_each(|p| p.descr.patch(patch, *key))
}
}
Target::Any { method_name: m } => {
if check(m, &method.names.0) {
method.doc.patch(patch, *key);
method
.params
.iter_mut()
.for_each(|p| p.descr.patch(patch, *key))
}
}
});
});
schema
}
static DOC_PATCHES: &[(Target, Patch)] = &[
(
Target::Any { method_name: None },
Patch::ReplaceLink {
name: "More info on Sending Files »",
value: "crate::types::InputFile",
},
),
(
Target::Field {
method_name: Some("sendChatAction"),
field_name: Some("action"),
},
Patch::ReplaceLink {
name: "text messages",
value: "crate::payloads::SendMessage",
},
),
(
Target::Field {
method_name: Some("sendChatAction"),
field_name: Some("action"),
},
Patch::ReplaceLink {
name: "photos",
value: "crate::payloads::SendPhoto",
},
),
(
Target::Field {
method_name: Some("sendChatAction"),
field_name: Some("action"),
},
Patch::ReplaceLink {
name: "videos",
value: "crate::payloads::SendVideo",
},
),
(
Target::Field {
method_name: Some("sendChatAction"),
field_name: Some("action"),
},
Patch::ReplaceLink {
name: "audio files",
value: "crate::payloads::SendAudio",
},
),
(
Target::Field {
method_name: Some("sendChatAction"),
field_name: Some("action"),
},
Patch::ReplaceLink {
name: "general files",
value: "crate::payloads::SendDocument",
},
),
(
Target::Field {
method_name: Some("sendChatAction"),
field_name: Some("action"),
},
Patch::ReplaceLink {
name: "location data",
value: "crate::payloads::SendLocation",
},
),
(
Target::Field {
method_name: Some("sendChatAction"),
field_name: Some("action"),
},
Patch::ReplaceLink {
name: "video notes",
value: "crate::payloads::SendVideoNote",
},
),
(
Target::Field {
method_name: Some("sendChatAction"),
field_name: Some("action"),
},
Patch::ReplaceLink {
name: "stickers",
value: "crate::payloads::SendSticker",
},
),
(
Target::Any { method_name: None },
Patch::Custom(intra_links),
),
(
Target::Method(Some("addStickerToSet")),
Patch::Replace {
text: "You **must** use exactly one of the fields _png\\_sticker_ or _tgs\\_sticker_. ",
with: "",
},
),
(
Target::Method(Some("GetFile")),
Patch::Replace {
text: "The file can then be downloaded via the link `https://api.telegram.org/file/bot<token>/<file_path>`, where `<file_path>` is taken from the response. It is guaranteed that the link will be valid for at least 1 hour. When the link expires, a new one can be requested by calling [`GetFile`] again.",
with: "The file can then be downloaded via the method [`Bot::download_file(file_path, dst)`], where `file_path` is taken from the response. It is guaranteed that the path from [`GetFile`] will be valid for at least 1 hour. When the path expires, a new one can be requested by calling [`GetFile`].",
},
),
(
Target::Method(Some("GetFile")),
Patch::AddLink {
name: "`Bot::download_file(file_path, dst)`",
value: "crate::net::Download::download_file",
},
),
// FIXME RETUNRS
];
#[derive(Debug, Clone, Copy)]
enum Target<'a> {
Any {
method_name: Option<&'a str>,
},
Method(Option<&'a str>),
Field {
method_name: Option<&'a str>,
field_name: Option<&'a str>,
},
}
impl<'a> Target<'a> {
fn is_exact(&self) -> bool {
match self {
Target::Method(m) => m.is_some(),
Target::Field {
method_name,
field_name,
} => method_name.is_some() && field_name.is_some(),
Target::Any { method_name: _ } => false,
}
}
}
enum Patch<'a> {
ReplaceLink { name: &'a str, value: &'a str },
AddLink { name: &'a str, value: &'a str },
// RemoveLink { name: &'a str },
// FullReplace { text: &'a str, with: &'a str },
Replace { text: &'a str, with: &'a str },
Custom(fn(&mut Doc)),
}
impl Doc {
fn patch(&mut self, patch: &Patch, key: Target) {
match patch {
Patch::ReplaceLink { name, value } => {
if let Some(link) = self.md_links.get_mut(*name) {
link.clear();
*link += *value;
} else if key.is_exact() {
panic!("Patch error: {:?} doesn't have link {}", key, name);
}
}
Patch::AddLink { name, value } => {
self.md_links
.insert((*name).to_owned(), (*value).to_owned());
}
// Patch::RemoveLink { name } => drop(self.md_links.remove(*name)),
// Patch::FullReplace { text, with } => {
// assert_eq!(self.md.as_str(), *text);
// self.md.clear();
// self.md += with;
// }
Patch::Replace { text, with } => self.md = self.md.replace(*text, with),
Patch::Custom(f) => f(self),
}
}
}
fn intra_links(doc: &mut Doc) {
let mut repls_t = Vec::new();
let mut repls_m = Vec::new();
doc.md_links
.iter_mut()
.filter(|(k, v)| {
v.starts_with("https://core.telegram.org/bots/api#")
&& !k.contains(&['-', '_', '.', ' '][..])
})
.for_each(|(k, v)| {
if let Some(c) = k.chars().next() {
match () {
_ if k == "games" => {}
_ if k == "unbanned" => *v = String::from("crate::payloads::UnbanChatMember"),
_ if c.is_lowercase() && !["update"].contains(&&&**k) => {
repls_m.push(k.clone());
*v = format!("crate::payloads::{}", to_uppercase(k));
}
_ => {
repls_t.push(k.clone());
*v = format!("crate::types::{}", k);
}
}
}
});
for repl in repls_t {
if let Some(value) = doc.md_links.remove(repl.as_str()) {
doc.md = doc
.md
.replace(format!("[{}]", repl).as_str(), &format!("[`{}`]", repl));
doc.md_links.insert(format!("`{}`", repl), value);
}
}
for repl in repls_m {
if let Some(value) = doc.md_links.remove(repl.as_str()) {
let repln = to_uppercase(&repl);
doc.md = doc
.md
.replace(format!("[{}]", repl).as_str(), &format!("[`{}`]", repln));
doc.md_links.insert(format!("`{}`", repln), value);
}
}
}
fn escape_kw(s: &mut String) {
if ["type"].contains(&s.as_str()) {
*s = format!("{}_", s);
}
}
fn to_uppercase(s: &str) -> String {
let mut chars = s.chars();
format!("{}{}", chars.next().unwrap().to_uppercase(), chars.as_str())
}
pub(crate) fn patch_ty(mut schema: Schema) -> Schema {
// URLs
patch_types(
&mut schema,
Type::String,
Type::Url,
&[("set_webhook", "url")],
);
patch_types(
&mut schema,
Type::Option(Box::new(Type::String)),
Type::Option(Box::new(Type::Url)),
&[
("answer_callback_query", "url"),
("send_invoice", "photo_url"),
],
);
// Dates
patch_types(
&mut schema,
Type::Option(Box::new(Type::u64)),
Type::Option(Box::new(Type::DateTime)),
&[
("send_poll", "close_date"),
("ban_chat_member", "until_date"),
("kick_chat_member", "until_date"),
("restrict_chat_member", "until_date"),
],
);
patch_types(
&mut schema,
Type::Option(Box::new(Type::i64)),
Type::Option(Box::new(Type::DateTime)),
&[
("create_chat_invite_link", "expire_date"),
("edit_chat_invite_link", "expire_date"),
],
);
schema
}
fn patch_types(schema: &mut Schema, from: Type, to: Type, list: &[(&str, &str)]) {
// URLs
for &(method, param) in list {
let m = schema
.methods
.iter_mut()
.find(|m| m.names.2 == method)
.expect("Couldn't find method for patching");
let p = m
.params
.iter_mut()
.find(|p| p.name == param)
.expect("Couldn't find parameter for patching");
assert_eq!(p.ty, from, "{}::{}", method, param);
p.ty = to.clone();
}
}

107
src/codegen/schema.rs Normal file
View file

@ -0,0 +1,107 @@
use std::fs;
use indexmap::IndexMap as HashMap;
use serde::{Deserialize, Serialize};
use crate::codegen::project_root;
pub fn get() -> Schema {
let path = project_root().join("schema.ron");
let text = fs::read_to_string(path).unwrap();
let schema = ron::from_str::<Schema>(&text).unwrap();
let schema = super::patch::patch_schema(schema);
let schema = super::patch::patch_ty(schema);
schema
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Schema {
pub api_version: ApiVersion,
pub methods: Vec<Method>,
pub tg_categories: HashMap<String, String>,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ApiVersion {
pub ver: String,
pub date: String,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Method {
pub names: (String, String, String),
pub return_ty: Type,
pub doc: Doc,
pub tg_doc: String,
pub tg_category: String,
#[serde(default)]
pub notes: Vec<Doc>,
pub params: Vec<Param>,
#[serde(default)]
pub sibling: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Doc {
pub md: String,
#[serde(default)]
pub md_links: HashMap<String, String>,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Param {
pub name: String,
pub ty: Type,
pub descr: Doc,
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub enum Type {
True,
u8,
u16,
u32,
i32,
u64,
i64,
f64,
bool,
String,
Option(Box<Type>),
ArrayOf(Box<Type>),
RawTy(String),
Url,
DateTime,
}
impl std::fmt::Display for Type {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Type::True => write!(f, "True"),
Type::u8 => write!(f, "u8"),
Type::u16 => write!(f, "u16"),
Type::u32 => write!(f, "u32"),
Type::i32 => write!(f, "i32"),
Type::u64 => write!(f, "u64"),
Type::i64 => write!(f, "i64"),
Type::f64 => write!(f, "f64"),
Type::bool => write!(f, "bool"),
Type::String => write!(f, "String"),
Type::Option(inner) => write!(f, "Option<{}>", inner),
Type::ArrayOf(inner) => write!(f, "Vec<{}>", inner),
Type::RawTy(raw) => f.write_str(raw),
Type::Url => write!(f, "Url"),
Type::DateTime => write!(f, "DateTime<Utc>"),
}
}
}

View file

@ -115,3 +115,6 @@ mod bot;
// implementation details
mod serde_multipart;
#[cfg(test)]
mod codegen;

View file

@ -399,14 +399,6 @@ macro_rules! download_forward {
};
}
// This macro is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS MACRO**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
macro_rules! requester_forward {
($i:ident $(, $rest:ident )* $(,)? => $body:ident, $ty:ident ) => {
requester_forward!(@method $i $body $ty);
@ -415,10 +407,14 @@ macro_rules! requester_forward {
)*
};
// START BLOCK requester_forward_at_method
// Generated by `codegen_requester_forward`, do not edit by hand.
(@method get_updates $body:ident $ty:ident) => {
type GetUpdates = $ty![GetUpdates];
fn get_updates(&self) -> Self::GetUpdates {
fn get_updates(&self, ) -> Self::GetUpdates {
let this = self;
$body!(get_updates this ())
}
@ -434,7 +430,7 @@ macro_rules! requester_forward {
(@method delete_webhook $body:ident $ty:ident) => {
type DeleteWebhook = $ty![DeleteWebhook];
fn delete_webhook(&self) -> Self::DeleteWebhook {
fn delete_webhook(&self, ) -> Self::DeleteWebhook {
let this = self;
$body!(delete_webhook this ())
}
@ -442,7 +438,7 @@ macro_rules! requester_forward {
(@method get_webhook_info $body:ident $ty:ident) => {
type GetWebhookInfo = $ty![GetWebhookInfo];
fn get_webhook_info(&self) -> Self::GetWebhookInfo {
fn get_webhook_info(&self, ) -> Self::GetWebhookInfo {
let this = self;
$body!(get_webhook_info this ())
}
@ -450,7 +446,7 @@ macro_rules! requester_forward {
(@method get_me $body:ident $ty:ident) => {
type GetMe = $ty![GetMe];
fn get_me(&self) -> Self::GetMe {
fn get_me(&self, ) -> Self::GetMe {
let this = self;
$body!(get_me this ())
}
@ -458,7 +454,7 @@ macro_rules! requester_forward {
(@method log_out $body:ident $ty:ident) => {
type LogOut = $ty![LogOut];
fn log_out(&self) -> Self::LogOut {
fn log_out(&self, ) -> Self::LogOut {
let this = self;
$body!(log_out this ())
}
@ -466,7 +462,7 @@ macro_rules! requester_forward {
(@method close $body:ident $ty:ident) => {
type Close = $ty![Close];
fn close(&self) -> Self::Close {
fn close(&self, ) -> Self::Close {
let this = self;
$body!(close this ())
}
@ -708,10 +704,10 @@ macro_rules! requester_forward {
(@method set_chat_administrator_custom_title $body:ident $ty:ident) => {
type SetChatAdministratorCustomTitle = $ty![SetChatAdministratorCustomTitle];
fn set_chat_administrator_custom_title<Ch, Cu>(&self, chat_id: Ch, user_id: UserId, custom_title: Cu) -> Self::SetChatAdministratorCustomTitle where Ch: Into<Recipient>,
Cu: Into<String> {
fn set_chat_administrator_custom_title<Ch, C>(&self, chat_id: Ch, user_id: UserId, custom_title: C) -> Self::SetChatAdministratorCustomTitle where Ch: Into<Recipient>,
C: Into<String> {
let this = self;
$body!(set_chat_administrator_custom_title this (chat_id: Ch, user_id: UserId, custom_title: Cu))
$body!(set_chat_administrator_custom_title this (chat_id: Ch, user_id: UserId, custom_title: C))
}
};
(@method ban_chat_sender_chat $body:ident $ty:ident) => {
@ -931,7 +927,7 @@ macro_rules! requester_forward {
(@method get_my_commands $body:ident $ty:ident) => {
type GetMyCommands = $ty![GetMyCommands];
fn get_my_commands(&self) -> Self::GetMyCommands {
fn get_my_commands(&self, ) -> Self::GetMyCommands {
let this = self;
$body!(get_my_commands this ())
}
@ -939,7 +935,7 @@ macro_rules! requester_forward {
(@method set_chat_menu_button $body:ident $ty:ident) => {
type SetChatMenuButton = $ty![SetChatMenuButton];
fn set_chat_menu_button(&self) -> Self::SetChatMenuButton {
fn set_chat_menu_button(&self, ) -> Self::SetChatMenuButton {
let this = self;
$body!(set_chat_menu_button this ())
}
@ -947,7 +943,7 @@ macro_rules! requester_forward {
(@method get_chat_menu_button $body:ident $ty:ident) => {
type GetChatMenuButton = $ty![GetChatMenuButton];
fn get_chat_menu_button(&self) -> Self::GetChatMenuButton {
fn get_chat_menu_button(&self, ) -> Self::GetChatMenuButton {
let this = self;
$body!(get_chat_menu_button this ())
}
@ -955,7 +951,7 @@ macro_rules! requester_forward {
(@method set_my_default_administrator_rights $body:ident $ty:ident) => {
type SetMyDefaultAdministratorRights = $ty![SetMyDefaultAdministratorRights];
fn set_my_default_administrator_rights(&self) -> Self::SetMyDefaultAdministratorRights {
fn set_my_default_administrator_rights(&self, ) -> Self::SetMyDefaultAdministratorRights {
let this = self;
$body!(set_my_default_administrator_rights this ())
}
@ -963,7 +959,7 @@ macro_rules! requester_forward {
(@method get_my_default_administrator_rights $body:ident $ty:ident) => {
type GetMyDefaultAdministratorRights = $ty![GetMyDefaultAdministratorRights];
fn get_my_default_administrator_rights(&self) -> Self::GetMyDefaultAdministratorRights {
fn get_my_default_administrator_rights(&self, ) -> Self::GetMyDefaultAdministratorRights {
let this = self;
$body!(get_my_default_administrator_rights this ())
}
@ -971,7 +967,7 @@ macro_rules! requester_forward {
(@method delete_my_commands $body:ident $ty:ident) => {
type DeleteMyCommands = $ty![DeleteMyCommands];
fn delete_my_commands(&self) -> Self::DeleteMyCommands {
fn delete_my_commands(&self, ) -> Self::DeleteMyCommands {
let this = self;
$body!(delete_my_commands this ())
}
@ -1224,5 +1220,117 @@ macro_rules! requester_forward {
let this = self;
$body!(get_game_high_scores this (user_id: UserId, target: T))
}
};
};// END BLOCK requester_forward_at_method
}
#[test]
fn codegen_requester_forward() {
use crate::codegen::{
add_hidden_preamble,
convert::{convert_for, Convert},
ensure_file_contents, min_prefix, project_root, reformat, replace_block,
schema::{self, Type},
to_uppercase,
};
use indexmap::IndexMap;
use itertools::Itertools;
let path = project_root().join("src/local_macros.rs");
let schema = schema::get();
let contents = schema
.methods
.iter()
.map(|m| {
let mut convert_params = m
.params
.iter()
.filter(|p| !matches!(p.ty, Type::Option(_)))
.map(|p| (&p.name, convert_for(&p.ty)))
.filter(|(_, c)| !matches!(c, Convert::Id(_)))
.map(|(name, _)| &**name)
.collect::<Vec<_>>();
convert_params.sort();
let prefixes: IndexMap<_, _> = convert_params
.iter()
.copied()
// Workaround to output the last type as the first letter
.chain(["\0"])
.tuple_windows()
.map(|(l, r)| (l, min_prefix(&l, &r)))
.collect();
let args = m
.params
.iter()
.filter(|p| !matches!(p.ty, Type::Option(_)))
.map(|p| match prefixes.get(&*p.name) {
Some(prefix) => format!("{}: {}", p.name, to_uppercase(prefix)),
None => format!("{}: {}", p.name, p.ty),
})
.join(", ");
let generics = m
.params
.iter()
.flat_map(|p| prefixes.get(&*p.name))
.copied()
.map(to_uppercase)
.join(", ");
let where_clause = m
.params
.iter()
.filter(|p| !matches!(p.ty, Type::Option(_)))
.flat_map(|p| match convert_for(&p.ty) {
Convert::Id(_) => None,
Convert::Into(ty) => Some(format!(
"{}: Into<{}>",
&to_uppercase(&prefixes[&*p.name]),
ty
)),
Convert::Collect(ty) => Some(format!(
"{}: IntoIterator<Item = {}>",
&to_uppercase(&prefixes[&*p.name]),
ty
)),
})
.join(",\n ");
let generics = if generics.is_empty() {
String::from("")
} else {
format!("<{}>", generics)
};
let where_clause = if where_clause.is_empty() {
String::from("")
} else {
format!(" where {}", where_clause)
};
format!(
"
(@method {method} $body:ident $ty:ident) => {{
type {Method} = $ty![{Method}];
fn {method}{generics}(&self, {args}) -> Self::{Method}{where_clause} {{
let this = self;
$body!({method} this ({args}))
}}
}};",
Method = m.names.1,
method = m.names.2,
)
})
.collect();
let contents = reformat(replace_block(
&path,
"requester_forward_at_method",
&add_hidden_preamble("codegen_requester_forward", contents),
));
ensure_file_contents(&path, &contents);
}

View file

@ -12,14 +12,9 @@
/// namespace.
pub mod setters;
// This block is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS BLOCK**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
// START BLOCK payload_modules
// Generated by `codegen_payload_mods_and_reexports`, do not edit by hand.
mod add_sticker_to_set;
mod answer_callback_query;
mod answer_inline_query;
@ -227,3 +222,64 @@ pub use unban_chat_sender_chat::{UnbanChatSenderChat, UnbanChatSenderChatSetters
pub use unpin_all_chat_messages::{UnpinAllChatMessages, UnpinAllChatMessagesSetters};
pub use unpin_chat_message::{UnpinChatMessage, UnpinChatMessageSetters};
pub use upload_sticker_file::{UploadStickerFile, UploadStickerFileSetters};
// END BLOCK payload_modules
/// Generates `mod`s and `pub use`s above.
#[test]
fn codegen_payload_mods_and_reexports() {
use crate::codegen::{
add_hidden_preamble, ensure_file_contents, project_root, reformat, replace_block, schema,
};
let path = project_root().join("src/payloads.rs");
let schema = schema::get();
let mut block = String::new();
schema
.methods
.iter()
.for_each(|m| block.push_str(&format!("mod {};\n", m.names.2)));
block.push('\n');
schema.methods.iter().for_each(|m| {
block.push_str(&format!(
"pub use {m}::{{{M}, {M}Setters}};\n",
m = m.names.2,
M = m.names.1
))
});
let contents = reformat(replace_block(
&path,
"payload_modules",
&add_hidden_preamble("codegen_payload_mods_and_reexports", block),
));
ensure_file_contents(&path, &contents);
}
/// Generates contents of [`setters`] module.
#[test]
fn codegen_setters_reexports() {
use crate::codegen::{
add_hidden_preamble, ensure_file_contents, project_root, reformat, schema,
};
let path = project_root().join("src/payloads/setters.rs");
let schema = schema::get();
let mut contents = String::new();
contents.push_str("#[doc(no_inline)] pub use crate::payloads::{");
schema
.methods
.iter()
.for_each(|m| contents.push_str(&format!("{M}Setters as _,", M = m.names.1)));
contents.push_str("};\n");
let contents = reformat(add_hidden_preamble("codegen_setters_reexports", contents));
ensure_file_contents(&path, &contents);
}
#[cfg(test)]
mod codegen;

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{InputSticker, MaskPosition, True, UserId};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use url::Url;

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{InlineQueryResult, True};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::True;

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{ShippingOption, True};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{InlineQueryResult, SentWebAppMessage};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{Recipient, True, UserId};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use chrono::{DateTime, Utc};
use serde::Serialize;

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{ChatId, Recipient, True};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::True;

269
src/payloads/codegen.rs Normal file
View file

@ -0,0 +1,269 @@
use std::{borrow::Borrow, collections::HashSet, ops::Deref};
use itertools::Itertools;
use crate::codegen::{
add_preamble,
convert::{convert_for, Convert},
ensure_files_contents, project_root, reformat,
schema::{self, Doc, Method, Param, Type},
to_uppercase,
};
#[test]
fn codegen_payloads() {
let base_path = project_root().join("src/payloads/");
let schema = schema::get();
let mut files = Vec::new();
for method in schema.methods {
let file_name = format!("{}.rs", method.names.2);
let path = base_path.join(&*file_name);
let uses = uses(&method);
let method_doc = render_doc(&method.doc, method.sibling.as_deref());
let eq_hash_derive = eq_hash_suitable(&method)
.then(|| " Eq, Hash,")
.unwrap_or("");
let default_derive = default_needed(&method).then(|| " Default,").unwrap_or("");
let return_ty = method.return_ty.to_string();
let required = params(
method
.params
.iter()
.filter(|p| !matches!(&p.ty, Type::Option(_))),
);
let required = match &*required {
"" => "".to_owned(),
_ => format!(" required {{\n{required}\n }}"),
};
let optional = params(method.params.iter().filter_map(|p| match &p.ty {
Type::Option(inner) => Some(Param {
name: p.name.clone(),
ty: inner.deref().clone(),
descr: p.descr.clone(),
}),
_ => None,
}));
let optional = match &*optional {
"" => "".to_owned(),
_ if required.is_empty() => format!(" optional {{\n{optional}\n }}"),
_ => format!("\n optional {{\n{optional}\n }}"),
};
let multipart = multipart_input_file_fields(&method)
.map(|field| format!(" @[multipart = {}]\n", field.join(", ")))
.unwrap_or(String::new());
let derive = if !multipart.is_empty()
|| matches!(
&*method.names.1,
"SendMediaGroup" | "EditMessageMedia" | "EditMessageMediaInline"
) {
format!("#[derive(Debug, Clone, Serialize)]")
} else {
format!("#[derive(Debug, PartialEq,{eq_hash_derive}{default_derive} Clone, Serialize)]")
};
let timeout_secs = match &*method.names.2 {
"get_updates" => " @[timeout_secs = timeout]\n",
_ => "",
};
let contents = format!(
"\
{uses}
impl_payload! {{
{multipart}{timeout_secs}{method_doc}
{derive}
pub {Method} ({Method}Setters) => {return_ty} {{
{required}{optional}
}}
}}
",
Method = method.names.1,
);
files.push((path, reformat(add_preamble("codegen_payloads", contents))));
}
ensure_files_contents(files.iter().map(|(p, c)| (&**p, &**c)))
}
fn uses(method: &Method) -> String {
enum Use {
Prelude,
Crate(String),
External(String),
}
fn ty_use(ty: &Type) -> Use {
match ty {
Type::True => Use::Crate(String::from("use crate::types::True;")),
Type::u8
| Type::u16
| Type::u32
| Type::i32
| Type::u64
| Type::i64
| Type::f64
| Type::bool
| Type::String => Use::Prelude,
Type::Option(inner) | Type::ArrayOf(inner) => ty_use(inner),
Type::RawTy(raw) => Use::Crate(["use crate::types::", &raw, ";"].concat()),
Type::Url => Use::External(String::from("use url::Url;")),
Type::DateTime => Use::External(String::from("use chrono::{DateTime, Utc};")),
}
}
let mut crate_uses = HashSet::new();
let mut external_uses = HashSet::new();
external_uses.insert(String::from("use serde::Serialize;"));
core::iter::once(&method.return_ty)
.chain(method.params.iter().map(|p| &p.ty))
.map(ty_use)
.for_each(|u| match u {
Use::Prelude => {}
Use::Crate(u) => {
crate_uses.insert(u);
}
Use::External(u) => {
external_uses.insert(u);
}
});
let external_uses = external_uses.into_iter().join("\n");
if crate_uses.is_empty() {
external_uses
} else {
let crate_uses = crate_uses.into_iter().join("");
format!("{external_uses}\n\n{crate_uses}",)
}
}
fn render_doc(doc: &Doc, sibling: Option<&str>) -> String {
let links = match &doc.md_links {
links if links.is_empty() => String::new(),
links => {
let l: String = links
.iter()
.map(|(name, link)| format!("\n /// [{name}]: {link}"))
.collect();
format!("\n ///{l}")
}
};
let sibling_note = sibling
.map(|s| {
format!(
"\n /// \n /// See also: [`{s}`](crate::payloads::{s})",
s = to_uppercase(s)
)
})
.unwrap_or_default();
[
" /// ",
&doc.md.replace("\n", "\n /// "),
&sibling_note,
&links,
]
.concat()
}
fn eq_hash_suitable(method: &Method) -> bool {
fn ty_eq_hash_suitable(ty: &Type) -> bool {
match ty {
Type::f64 => false,
Type::Option(inner) | Type::ArrayOf(inner) => ty_eq_hash_suitable(&*inner),
Type::True
| Type::u8
| Type::u16
| Type::u32
| Type::i32
| Type::u64
| Type::i64
| Type::bool
| Type::String => true,
Type::Url | Type::DateTime => true,
Type::RawTy(raw) => raw != "MaskPosition" && raw != "InlineQueryResult",
}
}
method.params.iter().all(|p| ty_eq_hash_suitable(&p.ty))
}
fn default_needed(method: &Method) -> bool {
method
.params
.iter()
.all(|p| matches!(p.ty, Type::Option(_)))
}
fn params(params: impl Iterator<Item = impl Borrow<Param>>) -> String {
params
.map(|param| {
let param = param.borrow();
let doc = render_doc(&param.descr, None).replace("\n", "\n ");
let field = &param.name;
let ty = &param.ty;
let flatten = match ty {
Type::RawTy(s) if s == "InputSticker" || s == "TargetMessage" => {
"\n #[serde(flatten)]"
}
_ => "",
};
let with = match ty {
Type::DateTime => {
"\n #[serde(with = \
\"crate::types::serde_opt_date_from_unix_timestamp\")]"
}
_ => "",
};
let rename = match field.strip_suffix('_') {
Some(field) => format!("\n #[serde(rename = \"{field}\")]"),
None => "".to_owned(),
};
let convert = match convert_for(ty) {
Convert::Id(_) => "",
Convert::Into(_) => " [into]",
Convert::Collect(_) => " [collect]",
};
format!(" {doc}{flatten}{with}{rename}\n pub {field}: {ty}{convert},")
})
.join("\n")
}
fn multipart_input_file_fields(m: &Method) -> Option<Vec<&str>> {
let fields: Vec<_> = m
.params
.iter()
.filter(|&p| ty_is_multiparty(&p.ty))
.map(|p| &*p.name)
.collect();
if fields.is_empty() {
None
} else {
Some(fields)
}
}
fn ty_is_multiparty(ty: &Type) -> bool {
matches!(ty, Type::RawTy(x) if x == "InputFile" || x == "InputSticker")
|| matches!(ty, Type::Option(inner) if ty_is_multiparty(inner))
}

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{MessageEntity, MessageId, ParseMode, Recipient, ReplyMarkup};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use chrono::{DateTime, Utc};
use serde::Serialize;

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::LabeledPrice;

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{InputSticker, MaskPosition, True, UserId};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{Recipient, True, UserId};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::Recipient;

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{Recipient, True};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{Recipient, True};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{BotCommandScope, True};
@ -16,7 +10,6 @@ impl_payload! {
/// [higher level commands]: https://core.telegram.org/bots/api#determining-list-of-commands
#[derive(Debug, PartialEq, Eq, Hash, Default, Clone, Serialize)]
pub DeleteMyCommands (DeleteMyCommandsSetters) => True {
optional {
/// A JSON-serialized object, describing scope of users for which the commands are relevant. Defaults to BotCommandScopeDefault.
pub scope: BotCommandScope,

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::True;

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::True;
@ -16,7 +10,6 @@ impl_payload! {
/// [`GetUpdates`]: crate::payloads::GetUpdates
#[derive(Debug, PartialEq, Eq, Hash, Default, Clone, Serialize)]
pub DeleteWebhook (DeleteWebhookSetters) => True {
optional {
/// Pass _True_ to drop all pending updates
pub drop_pending_updates: bool,

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use chrono::{DateTime, Utc};
use serde::Serialize;

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{InlineKeyboardMarkup, Message, MessageEntity, ParseMode, Recipient};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{InlineKeyboardMarkup, MessageEntity, ParseMode, True};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{Message, Recipient, ReplyMarkup};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{Message, ReplyMarkup};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{InlineKeyboardMarkup, InputMedia, Message, Recipient};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{InlineKeyboardMarkup, InputMedia, True};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{InlineKeyboardMarkup, Message, Recipient};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{InlineKeyboardMarkup, True};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{InlineKeyboardMarkup, Message, MessageEntity, ParseMode, Recipient};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{InlineKeyboardMarkup, MessageEntity, ParseMode, True};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::Recipient;

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{Message, Recipient};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{Chat, Recipient};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{ChatMember, Recipient};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{ChatMember, Recipient, UserId};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::Recipient;

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::Recipient;

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{ChatId, MenuButton};
@ -14,7 +8,6 @@ impl_payload! {
/// Use this method to get the current value of the bot's menu button in a private chat, or the default menu button.
#[derive(Debug, PartialEq, Eq, Hash, Default, Clone, Serialize)]
pub GetChatMenuButton (GetChatMenuButtonSetters) => MenuButton {
optional {
/// Unique identifier for the target private chat. If not specified, default bot's menu button will be returned
pub chat_id: ChatId [into],

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::File;

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{TargetMessage, True, UserId};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::Me;

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{BotCommand, BotCommandScope};
@ -16,7 +10,6 @@ impl_payload! {
/// [`BotCommand`]: crate::types::BotCommand
#[derive(Debug, PartialEq, Eq, Hash, Default, Clone, Serialize)]
pub GetMyCommands (GetMyCommandsSetters) => Vec<BotCommand> {
optional {
/// A JSON-serialized object, describing scope of users for which the commands are relevant. Defaults to BotCommandScopeDefault.
pub scope: BotCommandScope,

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::ChatAdministratorRights;
@ -14,7 +8,6 @@ impl_payload! {
/// Use this method to get the current value of the bot's menu button in a private chat, or the default menu button.
#[derive(Debug, PartialEq, Eq, Hash, Default, Clone, Serialize)]
pub GetMyDefaultAdministratorRights (GetMyDefaultAdministratorRightsSetters) => ChatAdministratorRights {
optional {
/// Pass _True_ to get default administrator rights of the bot in channels. Otherwise, default administrator rights of the bot for groups and supergroups will be returned.
pub for_channels: bool,

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::StickerSet;

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{AllowedUpdate, Update};
@ -18,7 +12,6 @@ impl_payload! {
/// [`Update`]: crate::types::Update
#[derive(Debug, PartialEq, Eq, Hash, Default, Clone, Serialize)]
pub GetUpdates (GetUpdatesSetters) => Vec<Update> {
optional {
/// Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as [`GetUpdates`] is called with an offset higher than its update_id. The negative offset can be specified to retrieve updates starting from -offset update from the end of the updates queue. All previous updates will forgotten.
///

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{UserId, UserProfilePhotos};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::WebhookInfo;

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use chrono::{DateTime, Utc};
use serde::Serialize;

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{Recipient, True};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::True;

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{Recipient, True};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{Recipient, True, UserId};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use chrono::{DateTime, Utc};
use serde::Serialize;

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::Recipient;

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{InputFile, Message, MessageEntity, ParseMode, Recipient, ReplyMarkup};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{InputFile, Message, MessageEntity, ParseMode, Recipient, ReplyMarkup};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{ChatAction, Recipient, True};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{Message, Recipient, ReplyMarkup};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{DiceEmoji, Message, Recipient, ReplyMarkup};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{InputFile, Message, MessageEntity, ParseMode, Recipient, ReplyMarkup};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{Message, ReplyMarkup};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use url::Url;

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{Message, Recipient, ReplyMarkup};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{InputMedia, Message, Recipient};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{Message, MessageEntity, ParseMode, Recipient, ReplyMarkup};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{InputFile, Message, MessageEntity, ParseMode, Recipient, ReplyMarkup};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use chrono::{DateTime, Utc};
use serde::Serialize;

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{InputFile, Message, Recipient, ReplyMarkup};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{Message, Recipient, ReplyMarkup};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{InputFile, Message, MessageEntity, ParseMode, Recipient, ReplyMarkup};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{InputFile, Message, Recipient, ReplyMarkup};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{InputFile, Message, MessageEntity, ParseMode, Recipient, ReplyMarkup};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{Recipient, True, UserId};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{Recipient, True};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{ChatId, MenuButton, True};
@ -14,7 +8,6 @@ impl_payload! {
/// Use this method to change the bot's menu button in a private chat, or the default menu button.
#[derive(Debug, PartialEq, Eq, Hash, Default, Clone, Serialize)]
pub SetChatMenuButton (SetChatMenuButtonSetters) => True {
optional {
/// Unique identifier for the target private chat. If not specified, default bot's menu button will be changed.
pub chat_id: ChatId [into],

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{ChatPermissions, Recipient, True};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{InputFile, Recipient, True};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{Recipient, True};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{Recipient, True};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{Message, UserId};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{Message, UserId};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{BotCommand, BotCommandScope, True};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{ChatAdministratorRights, True};
@ -14,7 +8,6 @@ impl_payload! {
/// Use this method to change the default administrator rights requested by the bot when it's added as an administrator to groups or channels. These rights will be suggested to users, but they are are free to modify the list before adding the bot.
#[derive(Debug, PartialEq, Eq, Hash, Default, Clone, Serialize)]
pub SetMyDefaultAdministratorRights (SetMyDefaultAdministratorRightsSetters) => True {
optional {
/// A JSON-serialized object describing new default administrator rights. If not specified, the default administrator rights will be cleared.
pub rights: ChatAdministratorRights,

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{PassportElementError, True, UserId};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::True;

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{InputFile, True, UserId};

View file

@ -1,11 +1,5 @@
// This file is auto generated by [`cg`] from [`schema`].
//
// **DO NOT EDIT THIS FILE**,
//
// Edit `cg` or `schema` instead.
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use url::Url;

Some files were not shown because too many files have changed in this diff Show more