From c89b1acb6e5d5755dc79c1f5643c915624a4c4c3 Mon Sep 17 00:00:00 2001 From: syn Date: Tue, 19 May 2020 20:54:45 +0300 Subject: Some kind of working code --- .gitignore | 1 + .gitmodules | 6 + Cargo.lock | 680 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 20 ++ build.rs | 14 ++ rust-tdlib | 1 + src/client.rs | 187 ++++++++++++++++ src/main.rs | 54 +++++ src/update.rs | 40 ++++ td | 1 + 10 files changed, 1004 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 build.rs create mode 160000 rust-tdlib create mode 100644 src/client.rs create mode 100644 src/main.rs create mode 100644 src/update.rs create mode 160000 td diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..ebcc167 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "rust-tdlib"] + path = rust-tdlib + url = https://github.com/lattenwald/rust-tdlib.git +[submodule "td"] + path = td + url = https://github.com/tdlib/td.git diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..0389729 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,680 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "aho-corasick" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada" +dependencies = [ + "memchr", +] + +[[package]] +name = "arc-swap" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b585a98a234c46fc563103e9278c9391fde1f4e6850334da895d27edb9580f62" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi 0.3.8", +] + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "bytes" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + +[[package]] +name = "env_logger" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +dependencies = [ + "bitflags", + "fuchsia-zircon-sys", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" + +[[package]] +name = "futures" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399" + +[[package]] +name = "futures-executor" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d6bb888be1153d3abeb9006b11b02cf5e9b209fda28693c31ae1e4e012e314" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789" + +[[package]] +name = "futures-macro" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc" + +[[package]] +name = "futures-task" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626" +dependencies = [ + "once_cell", +] + +[[package]] +name = "futures-util" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "hermit-abi" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61565ff7aaace3525556587bd2dc31d4a07071957be715e63ce7b1eccf51a8f4" +dependencies = [ + "libc", +] + +[[package]] +name = "humantime" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" +dependencies = [ + "quick-error", +] + +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", +] + +[[package]] +name = "json" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005" + +[[package]] +name = "log" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" + +[[package]] +name = "mio" +version = "0.6.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" +dependencies = [ + "cfg-if", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log", + "miow 0.2.1", + "net2", + "slab", + "winapi 0.2.8", +] + +[[package]] +name = "mio-named-pipes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5e374eff525ce1c5b7687c4cef63943e7686524a387933ad27ca7ec43779cb3" +dependencies = [ + "log", + "mio", + "miow 0.3.3", + "winapi 0.3.8", +] + +[[package]] +name = "mio-uds" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" +dependencies = [ + "iovec", + "libc", + "mio", +] + +[[package]] +name = "miow" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" +dependencies = [ + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", +] + +[[package]] +name = "miow" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226" +dependencies = [ + "socket2", + "winapi 0.3.8", +] + +[[package]] +name = "net2" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" +dependencies = [ + "cfg-if", + "libc", + "winapi 0.3.8", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d" + +[[package]] +name = "pert" +version = "0.1.0" +dependencies = [ + "dotenv", + "env_logger", + "futures", + "json", + "log", + "rust-tdlib", + "tokio", + "uuid", +] + +[[package]] +name = "pin-project" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81d480cb4e89522ccda96d0eed9af94180b7a5f93fb28f66e1fd7d68431663d1" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a82996f11efccb19b685b14b5df818de31c1edcee3daa256ab5775dd98e72feb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7505eeebd78492e0f6108f7171c4948dbb120ee8119d9d77d0afa5469bef67f" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "ppv-lite86" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea" + +[[package]] +name = "proc-macro-hack" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63" + +[[package]] +name = "proc-macro-nested" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694" + +[[package]] +name = "proc-macro2" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53f5ffe53a6b28e37c9c1ce74893477864d64f74778a93a4beb43c8fa167f639" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quote" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42934bc9c8ab0d3b273a16d8551c8f0fcff46be73276ca083ec2414c15c4ba5e" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom", + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core", +] + +[[package]] +name = "redox_syscall" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" + +[[package]] +name = "regex" +version = "1.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6020f034922e3194c711b82a627453881bc4682166cabb07134a10c26ba7692" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", + "thread_local", +] + +[[package]] +name = "regex-syntax" +version = "0.6.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae" + +[[package]] +name = "rust-tdlib" +version = "0.1.0" +dependencies = [ + "libc", + "log", +] + +[[package]] +name = "signal-hook-registry" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" +dependencies = [ + "arc-swap", + "libc", +] + +[[package]] +name = "slab" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" + +[[package]] +name = "socket2" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "winapi 0.3.8", +] + +[[package]] +name = "syn" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1425de3c33b0941002740a420b1a906a350b88d08b82b2c8a01035a3f9447bac" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "termcolor" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thread_local" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "tokio" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d099fa27b9702bed751524694adbe393e18b36b204da91eb1cbbbbb4a5ee2d58" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "iovec", + "lazy_static", + "libc", + "memchr", + "mio", + "mio-named-pipes", + "mio-uds", + "num_cpus", + "pin-project-lite", + "signal-hook-registry", + "slab", + "tokio-macros", + "winapi 0.3.8", +] + +[[package]] +name = "tokio-macros" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" + +[[package]] +name = "uuid" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11" +dependencies = [ + "rand", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + +[[package]] +name = "winapi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi 0.3.8", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..31bac94 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "pert" +version = "0.1.0" +authors = ["syn "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +"rust-tdlib" = { path = "rust-tdlib" } +# serde = { version = "1", features = ["derive"] } +json = "0.12" +dotenv = "0.15" +log = "0.4" +env_logger = "0.7" +futures = "0.3" +uuid = { version = "0.8", features = ["v4"] } +[dependencies.tokio] + version = "0.2" + features = ["full"] diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..eec334e --- /dev/null +++ b/build.rs @@ -0,0 +1,14 @@ +use std::path::PathBuf; +use std::env; + +fn main() { + let crate_root: PathBuf = env::var("CARGO_MANIFEST_DIR").unwrap().into(); + let tdlib_path: PathBuf = { + env::var("TDLIB_LIBRARY_PATH") + .map_or_else( + |_err| crate_root.join("td/build"), + |lib_path| PathBuf::from(lib_path) + ) + }; + println!("cargo:rustc-link-search={}", tdlib_path.to_string_lossy()); +} diff --git a/rust-tdlib b/rust-tdlib new file mode 160000 index 0000000..9457dac --- /dev/null +++ b/rust-tdlib @@ -0,0 +1 @@ +Subproject commit 9457dac8d48aaf7658c083601474f09be6d36496 diff --git a/src/client.rs b/src/client.rs new file mode 100644 index 0000000..db46819 --- /dev/null +++ b/src/client.rs @@ -0,0 +1,187 @@ +use log::{ info, error, warn, trace }; +use rust_tdlib::Tdlib; +use std::{ + task::{ Waker, Context, Poll }, + future::Future, + pin::Pin, + sync::{ + mpsc::{ Sender, Receiver, channel }, + Arc, + Mutex + }, + thread, +}; +use uuid::Uuid; +use std::collections::HashMap; +use json::JsonValue; + + +#[derive(Debug)] +pub struct RequestData { + req: JsonValue, + resp: Option, + waker: Option, +} + +#[derive(Debug, Clone)] +pub struct RequestFuture { + data: Arc> +} + +impl Future for RequestFuture { + type Output = JsonValue; + + fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll { + let mut data = self.data.lock().unwrap(); + if let Some(resp) = &data.resp { + Poll::Ready(resp.clone()) + } else { + data.waker = Some(cx.waker().clone()); + Poll::Pending + } + } +} + +#[derive(Debug)] +enum JoinStreams { + NewRequest(RequestFuture), + NewResponse(String), +} + +#[derive(Debug)] +pub struct Client { + //waker_handle: std::thread::JoinHandle<()>, + sender: Sender, +} + +impl Client { + pub fn new(log_opt: Option) -> Self { + if let Some(log) = log_opt { + Tdlib::set_log_verbosity_level(log).ok(); + } + let (tx, rx) = channel(); + let tx_for_tg = tx.clone(); + let api = Arc::new(Tdlib::new()); + let api_for_listener = api.clone(); + let api_for_responder = api.clone(); + let rt = tokio::runtime::Handle::try_current().expect("Must be in runtime already"); + let _run_handle = thread::spawn( + move || OneshotResponder::new(rx, api_for_responder).run(rt) + ); + let _tg_handle = thread::spawn( + move || Self::listen_tg(tx_for_tg, api_for_listener, 1.0) + ); + + Self { + //waker_handle: _run_handle, + sender: tx + } + } + + pub fn send(&mut self, req: &JsonValue) -> RequestFuture { + let request = RequestData { + req: req.to_owned(), + resp: None, + waker: None + }; + let fut = RequestFuture { + data: Arc::new(Mutex::new(request)) + }; + + self.sender.send(JoinStreams::NewRequest(fut.clone())).unwrap(); + fut + } + + fn listen_tg(tx: Sender, api: Arc, timeout: f64) { + loop { + if let Some(msg) = api.receive(timeout) { + tx.send(JoinStreams::NewResponse(msg)).unwrap(); + } else { + info!("receive timed out"); + } + } + } +} + +#[derive(Debug)] +struct OneshotResponder { + api: Arc, + wakers_map: HashMap, + rx: Receiver, +} + +impl OneshotResponder { + fn new(rx: Receiver, api: Arc) -> Self { + Self { + api: api, + wakers_map: HashMap::new(), + rx: rx + } + } + + fn run(&mut self, rt: tokio::runtime::Handle) { + let mut updater = crate::update::UpdateRouter::new(rt); + updater.add_handler("updateOption", |val: JsonValue| { async move { info!("async update: {}", val) } }); + loop { + match self.rx.recv() { + Ok(JoinStreams::NewRequest(fut)) => { + let id = loop { + let id = Uuid::new_v4(); + if self.wakers_map.contains_key(&id) { + continue; + } else { + break id; + } + }; + let data = fut.data.clone(); + let request: &mut JsonValue = &mut data.lock().unwrap().req; + if request.has_key("@extra") { + warn!("overwriting @extra in request"); + } + request["@extra"] = JsonValue::from(id.to_hyphenated().to_string()); + self.api.send(request.dump().as_ref()); + self.wakers_map.insert(id, fut); + trace!("new req:\n{}", json::stringify_pretty(request.clone(), 2)); + }, + Ok(JoinStreams::NewResponse(resp)) => { + match json::parse(resp.as_ref()) { + Ok(val) => { + trace!("received update: {}", val); + let typ = val["@type"].as_str().unwrap(); + if typ.starts_with("update") { + updater.dispatch(val); + } else { + self.handle_response(val); + } + }, + Err(e) => { + warn!("ignoring invalid response. err: {}, resp: {}", e, resp); + } + } + }, + Err(e) => { + error!("stream closed: {}", e); + error!("closing thread"); + break; + } + } + } + } + + fn handle_response(&mut self, resp: JsonValue) { + if let Some(id_str) = resp["@extra"].as_str() { + if let Ok(id) = Uuid::parse_str(id_str) { + let fut_data = self.wakers_map + .remove(&id) + .unwrap() + .data; + fut_data.lock().unwrap().resp = Some(resp); + fut_data.lock().unwrap() + .waker.as_ref() + .and_then(|waker: &Waker| { waker.clone().wake(); Some(()) }); + } + } else { + warn!("update has invalid @extra: {}", resp); + } + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..289ad02 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,54 @@ +use std::env; +use tokio; + +mod client; +//mod auth; +mod update; +//mod message; + +#[tokio::main] +async fn main() { + dotenv::dotenv().ok(); + env_logger::init(); + let tg_log: Option = env::var("TG_LOG") + .ok() + .and_then(|var| var.parse().ok()); + + let mut tg = client::Client::new(tg_log); + + tokio::spawn(async move { + let _auth_state = tg.send( + &json::object!{ + "@type": "getAuthorizationState" + } + ).await; + let cache = env::current_dir().unwrap().join("cache"); + let resp = tg.send(&json::object!{ + "@type": "setTdlibParameters", + "parameters": { + "use_test_dc": false, + "api_id": env::var("API_ID").unwrap(), + "api_hash": env::var("API_HASH").unwrap(), + "device_model": "mbia", + "system_version": "Catalina", + "application_version": "0.1", + "system_language_code": "en", + "database_directory": cache.join("database").to_str().unwrap(), + "use_message_database": false, + "files_directory": cache.join("files").to_str().unwrap(), + "use_secret_chats": false, + }, + }).await; + println!("resp: {}", resp); + }); + std::thread::sleep(std::time::Duration::new(1, 0)); +} + + +/* +fn main() { + runtime::Runtime::new(|arc_msg, tx| { + tx.send(std::sync::Arc::new(runtime::Task{})).unwrap(); + }).run(); +} +*/ diff --git a/src/update.rs b/src/update.rs new file mode 100644 index 0000000..a6884e3 --- /dev/null +++ b/src/update.rs @@ -0,0 +1,40 @@ +use std::collections::HashMap; +use json::JsonValue; +use std::future::Future; +use futures::future::BoxFuture; + +pub trait Handler: Send + Sync + 'static { + fn handle(&self, _: JsonValue) -> BoxFuture<'static, ()>; +} + +impl Handler for C +where C: Send + Sync + 'static + Fn(JsonValue) -> F, + F: Future + 'static + Send { + fn handle(&self, req: JsonValue) -> BoxFuture<'static, ()> { + Box::pin((*self)(req)) + } +} + +pub struct UpdateRouter { + router: HashMap>, + rt: tokio::runtime::Handle, +} + +impl UpdateRouter { + pub fn new(rt: tokio::runtime::Handle) -> Self { + Self { + router: HashMap::new(), + rt: rt + } + } + pub fn add_handler(&mut self, update_type: &str, handler: H) { + self.router.insert(update_type.to_owned(), Box::new(handler)); + } + + pub fn dispatch(&self, update: JsonValue) { + let update_type: &str = update["@type"].as_str().unwrap(); + self.router.get(update_type) + .and_then(|handler| { self.rt.spawn(handler.handle(update)); Some(()) }) + .or_else(|| { println!("handler not found"); Some(()) }); + } +} diff --git a/td b/td new file mode 160000 index 0000000..f2cb3af --- /dev/null +++ b/td @@ -0,0 +1 @@ +Subproject commit f2cb3afaef62f2dba2a0dc3dc63e374beabcb2df -- cgit v1.2.1-18-gbd029