Compare commits
2 commits
master
...
d9d94daaca
Author | SHA1 | Date | |
---|---|---|---|
famfo | d9d94daaca | ||
famfo | d955bef06e |
43
Cargo.toml
43
Cargo.toml
|
@ -8,40 +8,23 @@ license = "Unlicense"
|
|||
name = "async-circe"
|
||||
readme = "README.md"
|
||||
repository = "https://git.karx.xyz/circe/async-circe.git"
|
||||
version = "0.2.3"
|
||||
version = "0.3.0"
|
||||
|
||||
[dependencies.toml]
|
||||
version = "0.5"
|
||||
optional = true
|
||||
[dependencies]
|
||||
parking_lot = "0.11"
|
||||
tokio = {version = "1.15", features = ["io-util", "net", "rt", "fs"]}
|
||||
tracing = "0.1"
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1.0"
|
||||
optional = true
|
||||
# TLS
|
||||
tokio-rustls = {version = "0.23", optional = true}
|
||||
webpki-roots = {version = "0.22", optional = true}
|
||||
|
||||
[dependencies.serde_derive]
|
||||
version = "1.0"
|
||||
optional = true
|
||||
|
||||
[dependencies.tokio]
|
||||
version = "1.15"
|
||||
features = ["io-util", "net"]
|
||||
|
||||
[dependencies.tokio-native-tls]
|
||||
version= "0.3"
|
||||
optional = true
|
||||
|
||||
[dependencies.native-tls]
|
||||
version= "0.2"
|
||||
optional = true
|
||||
|
||||
[dependencies.tracing]
|
||||
version = "0.1"
|
||||
# Config from toml
|
||||
toml = {version = "0.5", optional = true}
|
||||
serde = {version = "1.0", optional = true}
|
||||
serde_derive = {version = "1.0", optional = true}
|
||||
|
||||
[features]
|
||||
default = ["tls"]
|
||||
tls = ["tokio-native-tls", "native-tls"]
|
||||
tls = ["tokio-rustls", "webpki-roots"]
|
||||
toml_config = ["toml", "serde", "serde_derive"]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
|
353
examples/basic-config/Cargo.lock
generated
353
examples/basic-config/Cargo.lock
generated
|
@ -4,20 +4,15 @@ version = 3
|
|||
|
||||
[[package]]
|
||||
name = "async-circe"
|
||||
version = "0.2.2"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"native-tls",
|
||||
"parking_lot",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tokio-rustls",
|
||||
"tracing",
|
||||
"webpki-roots",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "basic-config"
|
||||
version = "0.1.0"
|
||||
|
@ -32,6 +27,12 @@ version = "1.3.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.1.0"
|
||||
|
@ -51,45 +52,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.2"
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
dependencies = [
|
||||
"foreign-types-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
|
||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -104,6 +81,15 @@ version = "0.2.107"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
|
@ -141,24 +127,6 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"log",
|
||||
"openssl",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ntapi"
|
||||
version = "0.3.6"
|
||||
|
@ -175,36 +143,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.38"
|
||||
name = "parking_lot"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95"
|
||||
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-sys",
|
||||
"instant",
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.4"
|
||||
name = "parking_lot_core"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb"
|
||||
checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"instant",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -213,18 +173,6 @@ version = "0.2.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.32"
|
||||
|
@ -243,46 +191,6 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_hc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.10"
|
||||
|
@ -293,46 +201,59 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
version = "0.5.3"
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
|
||||
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"spin",
|
||||
"untrusted",
|
||||
"web-sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.19"
|
||||
name = "rustls"
|
||||
version = "0.20.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75"
|
||||
checksum = "d37e5e2290f3e040b594b1a9e04377c2c671f1a1cfd9bfdef82106ac1c113f84"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"winapi",
|
||||
"log",
|
||||
"ring",
|
||||
"sct",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.4.2"
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "sct"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"security-framework-sys",
|
||||
"ring",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "2.4.2"
|
||||
name = "smallvec"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
|
@ -345,20 +266,6 @@ dependencies = [
|
|||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"rand",
|
||||
"redox_syscall",
|
||||
"remove_dir_all",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.15.0"
|
||||
|
@ -386,13 +293,14 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-native-tls"
|
||||
version = "0.3.0"
|
||||
name = "tokio-rustls"
|
||||
version = "0.23.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
|
||||
checksum = "a27d5f2b839802bd8267fa19b0530f5a08b9c08cd417976be2a65d130fe1c11b"
|
||||
dependencies = [
|
||||
"native-tls",
|
||||
"rustls",
|
||||
"tokio",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -434,16 +342,93 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
name = "untrusted"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.2+wasi-snapshot-preview1"
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||
checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.22.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "552ceb903e957524388c4d3475725ff2c8b7960922063af6ce53c9a43da07449"
|
||||
dependencies = [
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
|
|
|
@ -1,20 +1,22 @@
|
|||
use async_circe::{commands::Command, Client, Config};
|
||||
use async_circe::client::{Client, Config};
|
||||
use async_circe::commands::parser::Command;
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn main() -> Result<(), tokio::io::Error> {
|
||||
let config = Config::new(
|
||||
&["#main", "#no-normies"],
|
||||
"karx.xyz",
|
||||
Some("+B"),
|
||||
Some("async-circe"),
|
||||
6697,
|
||||
"circe",
|
||||
);
|
||||
let mut client = Client::new(config).await.unwrap();
|
||||
client.identify().await.unwrap();
|
||||
Some("async-circe"),
|
||||
Some("+B"),
|
||||
&["#main", "#no-normies"],
|
||||
)
|
||||
.await;
|
||||
let (client, mut recv) = Client::new(config).await;
|
||||
client.identify(&mut recv).await.unwrap();
|
||||
|
||||
loop {
|
||||
if let Some(command) = client.read().await? {
|
||||
if let Some(command) = recv.read().await? {
|
||||
if let Command::PRIVMSG(nick, channel, message) = command {
|
||||
println!("{} in {}: {}", nick, channel, message);
|
||||
}
|
||||
|
|
353
examples/config-from-toml/Cargo.lock
generated
353
examples/config-from-toml/Cargo.lock
generated
|
@ -4,29 +4,30 @@ version = 3
|
|||
|
||||
[[package]]
|
||||
name = "async-circe"
|
||||
version = "0.2.2"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"native-tls",
|
||||
"parking_lot",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tokio-rustls",
|
||||
"toml",
|
||||
"tracing",
|
||||
"webpki-roots",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.1.0"
|
||||
|
@ -54,45 +55,21 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.2"
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
dependencies = [
|
||||
"foreign-types-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
|
||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -107,6 +84,15 @@ version = "0.2.107"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
|
@ -144,24 +130,6 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"log",
|
||||
"openssl",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ntapi"
|
||||
version = "0.3.6"
|
||||
|
@ -178,36 +146,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.38"
|
||||
name = "parking_lot"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95"
|
||||
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-sys",
|
||||
"instant",
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.4"
|
||||
name = "parking_lot_core"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.70"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6517987b3f8226b5da3661dad65ff7f300cc59fb5ea8333ca191fc65fde3edf"
|
||||
checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"instant",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -216,18 +176,6 @@ version = "0.2.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.32"
|
||||
|
@ -246,46 +194,6 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_hc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.10"
|
||||
|
@ -296,45 +204,46 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
version = "0.5.3"
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
|
||||
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"spin",
|
||||
"untrusted",
|
||||
"web-sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.19"
|
||||
name = "rustls"
|
||||
version = "0.20.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75"
|
||||
checksum = "d37e5e2290f3e040b594b1a9e04377c2c671f1a1cfd9bfdef82106ac1c113f84"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"winapi",
|
||||
"log",
|
||||
"ring",
|
||||
"sct",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.4.2"
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"security-framework-sys",
|
||||
]
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "2.4.2"
|
||||
name = "sct"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e"
|
||||
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"ring",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -354,6 +263,18 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.81"
|
||||
|
@ -365,20 +286,6 @@ dependencies = [
|
|||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"rand",
|
||||
"redox_syscall",
|
||||
"remove_dir_all",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.15.0"
|
||||
|
@ -406,13 +313,14 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-native-tls"
|
||||
version = "0.3.0"
|
||||
name = "tokio-rustls"
|
||||
version = "0.23.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
|
||||
checksum = "a27d5f2b839802bd8267fa19b0530f5a08b9c08cd417976be2a65d130fe1c11b"
|
||||
dependencies = [
|
||||
"native-tls",
|
||||
"rustls",
|
||||
"tokio",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -463,16 +371,93 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
name = "untrusted"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.2+wasi-snapshot-preview1"
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||
checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.22.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "552ceb903e957524388c4d3475725ff2c8b7960922063af6ce53c9a43da07449"
|
||||
dependencies = [
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
use async_circe::{commands::Command, Client, Config};
|
||||
use async_circe::client::{Client, Config};
|
||||
use async_circe::commands::parser::Command;
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn main() -> Result<(), std::io::Error> {
|
||||
let config = Config::from_toml("Config.toml")?;
|
||||
let mut client = Client::new(config).await.unwrap();
|
||||
client.identify().await.unwrap();
|
||||
let config = Config::new_toml("Config.toml").await?;
|
||||
let (client, mut recv) = Client::new(config).await;
|
||||
client.identify(&mut recv).await.unwrap();
|
||||
|
||||
loop {
|
||||
if let Some(command) = client.read().await? {
|
||||
if let Some(command) = recv.read().await? {
|
||||
if let Command::PRIVMSG(nick, channel, message) = command {
|
||||
println!("{} in {}: {}", nick, channel, message);
|
||||
}
|
||||
|
|
347
examples/debugging/Cargo.lock
generated
347
examples/debugging/Cargo.lock
generated
|
@ -13,20 +13,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "async-circe"
|
||||
version = "0.2.3"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"native-tls",
|
||||
"parking_lot",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tokio-rustls",
|
||||
"tracing",
|
||||
"webpki-roots",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "basic-config"
|
||||
version = "0.1.0"
|
||||
|
@ -42,6 +37,12 @@ version = "1.3.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.1.0"
|
||||
|
@ -61,45 +62,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.2"
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
dependencies = [
|
||||
"foreign-types-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
|
||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -114,6 +91,15 @@ version = "0.2.112"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
|
@ -160,24 +146,6 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"log",
|
||||
"openssl",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ntapi"
|
||||
version = "0.3.6"
|
||||
|
@ -194,36 +162,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.38"
|
||||
name = "parking_lot"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95"
|
||||
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-sys",
|
||||
"instant",
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.4"
|
||||
name = "parking_lot_core"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb"
|
||||
checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"instant",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -232,18 +192,6 @@ version = "0.2.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.36"
|
||||
|
@ -262,46 +210,6 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_hc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.10"
|
||||
|
@ -336,45 +244,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
version = "0.5.3"
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
|
||||
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"spin",
|
||||
"untrusted",
|
||||
"web-sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.19"
|
||||
name = "rustls"
|
||||
version = "0.20.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75"
|
||||
checksum = "d37e5e2290f3e040b594b1a9e04377c2c671f1a1cfd9bfdef82106ac1c113f84"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"winapi",
|
||||
"log",
|
||||
"ring",
|
||||
"sct",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.4.2"
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"security-framework-sys",
|
||||
]
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "2.4.2"
|
||||
name = "sct"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e"
|
||||
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"ring",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -392,6 +301,12 @@ version = "1.7.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.84"
|
||||
|
@ -403,20 +318,6 @@ dependencies = [
|
|||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"rand",
|
||||
"redox_syscall",
|
||||
"remove_dir_all",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.3"
|
||||
|
@ -453,13 +354,14 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-native-tls"
|
||||
version = "0.3.0"
|
||||
name = "tokio-rustls"
|
||||
version = "0.23.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
|
||||
checksum = "a27d5f2b839802bd8267fa19b0530f5a08b9c08cd417976be2a65d130fe1c11b"
|
||||
dependencies = [
|
||||
"native-tls",
|
||||
"rustls",
|
||||
"tokio",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -530,16 +432,93 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
name = "untrusted"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.2+wasi-snapshot-preview1"
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||
checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.22.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "552ceb903e957524388c4d3475725ff2c8b7960922063af6ce53c9a43da07449"
|
||||
dependencies = [
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use async_circe::{commands::Command, Client, Config};
|
||||
use async_circe::client::{Client, Config};
|
||||
use async_circe::commands::parser::Command;
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn main() -> Result<(), tokio::io::Error> {
|
||||
|
@ -9,18 +10,19 @@ async fn main() -> Result<(), tokio::io::Error> {
|
|||
.init();
|
||||
|
||||
let config = Config::new(
|
||||
&["#main", "#no-normies"],
|
||||
"karx.xyz",
|
||||
Some("+B"),
|
||||
Some("async-circe"),
|
||||
6697,
|
||||
"circe",
|
||||
);
|
||||
let mut client = Client::new(config).await.unwrap();
|
||||
client.identify().await.unwrap();
|
||||
Some("async-circe"),
|
||||
Some("+B"),
|
||||
&["#main", "#no-normies"],
|
||||
)
|
||||
.await;
|
||||
let (client, mut recv) = Client::new(config).await;
|
||||
client.identify(&mut recv).await.unwrap();
|
||||
|
||||
loop {
|
||||
if let Some(command) = client.read().await? {
|
||||
if let Some(command) = recv.read().await? {
|
||||
if let Command::PRIVMSG(nick, channel, message) = command {
|
||||
println!("{} in {}: {}", nick, channel, message);
|
||||
}
|
||||
|
|
|
@ -1,20 +1,22 @@
|
|||
use async_circe::{commands::Command, Client, Config};
|
||||
use async_circe::client::{Client, Config};
|
||||
use async_circe::commands::parser::Command;
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn main() -> Result<(), tokio::io::Error> {
|
||||
let config = Config::new(
|
||||
&["#main", "#no-normies"],
|
||||
"192.168.178.100",
|
||||
Some("+B"),
|
||||
Some("async-circe"),
|
||||
6667,
|
||||
"async-circe",
|
||||
);
|
||||
let mut client = Client::new(config).await.unwrap();
|
||||
client.identify().await.unwrap();
|
||||
"circe",
|
||||
Some("async-circe"),
|
||||
Some("+B"),
|
||||
&["#main", "#no-normies"],
|
||||
)
|
||||
.await;
|
||||
let (client, mut recv) = Client::new(config).await;
|
||||
client.identify(&mut recv).await.unwrap();
|
||||
|
||||
loop {
|
||||
if let Some(command) = client.read().await? {
|
||||
if let Some(command) = recv.read().await? {
|
||||
if let Command::PRIVMSG(nick, channel, message) = command {
|
||||
println!("{} in {}: {}", nick, channel, message);
|
||||
}
|
||||
|
|
80
src/client/config.rs
Normal file
80
src/client/config.rs
Normal file
|
@ -0,0 +1,80 @@
|
|||
use std::string::ToString;
|
||||
|
||||
#[cfg(feature = "toml_config")]
|
||||
use serde_derive::Deserialize;
|
||||
#[cfg(feature = "toml_config")]
|
||||
use std::path::Path;
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
#[cfg_attr(feature = "toml_config", derive(Deserialize))]
|
||||
pub struct Config {
|
||||
pub host: String,
|
||||
pub port: u16,
|
||||
pub username: String,
|
||||
pub nickname: Option<String>,
|
||||
pub mode: Option<String>,
|
||||
pub channels: Vec<String>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
/// Creates new config for a circe client
|
||||
pub async fn new(
|
||||
host: &'static str,
|
||||
port: u16,
|
||||
username: &'static str,
|
||||
nickname: Option<&'static str>,
|
||||
mode: Option<&'static str>,
|
||||
channels: &[&'static str],
|
||||
) -> Self {
|
||||
let nickname = nickname.map(ToString::to_string);
|
||||
let mode = mode.map(ToString::to_string);
|
||||
let channels = {
|
||||
let mut channel_vec = Vec::new();
|
||||
for channel in channels {
|
||||
channel_vec.push((*channel).to_string());
|
||||
}
|
||||
channel_vec
|
||||
};
|
||||
|
||||
Config {
|
||||
host: host.into(),
|
||||
port,
|
||||
username: username.into(),
|
||||
nickname,
|
||||
mode,
|
||||
channels,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates new config for a circe client
|
||||
pub async fn new_runtime(
|
||||
host: String,
|
||||
port: u16,
|
||||
username: String,
|
||||
nickname: Option<String>,
|
||||
mode: Option<String>,
|
||||
channels: Vec<String>,
|
||||
) -> Self {
|
||||
Config {
|
||||
host,
|
||||
port,
|
||||
username,
|
||||
nickname,
|
||||
mode,
|
||||
channels,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates new config for a circe client from a toml file
|
||||
#[cfg(feature = "toml_config")]
|
||||
pub async fn new_toml<P: AsRef<Path>>(file: P) -> Result<Self, tokio::io::Error> {
|
||||
use tokio::fs::File;
|
||||
use tokio::io::{AsyncReadExt, Error, ErrorKind};
|
||||
|
||||
let mut file = File::open(&file).await?;
|
||||
let mut config = String::new();
|
||||
file.read_to_string(&mut config).await?;
|
||||
toml::from_str(&config)
|
||||
.map_err(|e| Error::new(ErrorKind::Other, format!("Invalid TOML: {}", e)))
|
||||
}
|
||||
}
|
499
src/client/mod.rs
Normal file
499
src/client/mod.rs
Normal file
|
@ -0,0 +1,499 @@
|
|||
pub mod config;
|
||||
|
||||
pub use crate::client::config::Config;
|
||||
use crate::commands::parser::{CapMode, Command};
|
||||
use crate::stream::read::Read;
|
||||
use crate::stream::write::Write;
|
||||
|
||||
use tokio::io::{split, BufReader, Error};
|
||||
use tokio::net::TcpStream;
|
||||
|
||||
#[cfg(feature = "tls")]
|
||||
use std::sync::Arc;
|
||||
#[cfg(feature = "tls")]
|
||||
use tokio_rustls::rustls::{self, OwnedTrustAnchor};
|
||||
#[cfg(feature = "tls")]
|
||||
use tokio_rustls::TlsConnector;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Client {
|
||||
config: Config,
|
||||
tx: Write,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
/// Creates a new circe client
|
||||
pub async fn new(config: config::Config) -> (Self, Read) {
|
||||
let stream = TcpStream::connect(format!("{}:{}", config.host, config.port))
|
||||
.await
|
||||
.expect("Failed to connect to the server");
|
||||
|
||||
#[cfg(feature = "tls")]
|
||||
{
|
||||
let mut root_cert_store = rustls::RootCertStore::empty();
|
||||
root_cert_store.add_server_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.0.iter().map(
|
||||
|ta| {
|
||||
OwnedTrustAnchor::from_subject_spki_name_constraints(
|
||||
ta.subject,
|
||||
ta.spki,
|
||||
ta.name_constraints,
|
||||
)
|
||||
},
|
||||
));
|
||||
|
||||
let tls_config = rustls::ClientConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_root_certificates(root_cert_store)
|
||||
.with_no_client_auth();
|
||||
|
||||
let domain =
|
||||
rustls::ServerName::try_from(config.host.as_str()).expect("Invalid DNS name");
|
||||
let connector = TlsConnector::from(Arc::new(tls_config));
|
||||
let tls_stream = connector
|
||||
.connect(domain, stream)
|
||||
.await
|
||||
.expect("Failed to connect to the server");
|
||||
|
||||
let (recv, tx) = split(tls_stream);
|
||||
let recv = Read::new(BufReader::new(recv));
|
||||
let tx = Write::new(tx).await;
|
||||
|
||||
tracing::info!("New client created");
|
||||
(Self { config, tx }, recv)
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "tls"))]
|
||||
{
|
||||
let (recv, tx) = split(stream);
|
||||
let recv = Read::new(BufReader::new(recv));
|
||||
let tx = Write::new(tx).await;
|
||||
|
||||
tracing::info!("New client created");
|
||||
(Self { config, tx }, recv)
|
||||
}
|
||||
}
|
||||
|
||||
/// Identifys the client on the server
|
||||
/// # Errors
|
||||
/// Returns errors from the ``TcpStream``.
|
||||
pub async fn identify(self, recv: &mut Read) -> Result<(), Error> {
|
||||
let config = self.config.clone();
|
||||
self.clone().cap_mode(CapMode::LS).await?;
|
||||
self.clone().cap_mode(CapMode::END).await?;
|
||||
self.clone()
|
||||
.user(
|
||||
self.config.username.clone(),
|
||||
"*",
|
||||
"*",
|
||||
self.config.username.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
if let Some(nick) = self.config.nickname.clone() {
|
||||
self.clone().nick(&nick).await?;
|
||||
} else {
|
||||
self.clone().nick(&self.config.username.clone()).await?;
|
||||
}
|
||||
|
||||
loop {
|
||||
if let Some(command) = recv.read().await? {
|
||||
match command {
|
||||
Command::PING(code) => {
|
||||
self.clone().pong(&code).await?;
|
||||
}
|
||||
Command::OTHER(line) => {
|
||||
if line.contains("001") {
|
||||
break;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let user = {
|
||||
if let Some(nick) = config.nickname {
|
||||
nick
|
||||
} else {
|
||||
config.username
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(mode) = config.mode {
|
||||
self.clone().mode(&user, Some(&mode)).await?;
|
||||
}
|
||||
|
||||
for channel in &config.channels {
|
||||
self.clone().join(channel).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// TODO: rewrite
|
||||
|
||||
/// Request information about the admin of a given server.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # use async_circe::*;
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.admin("libera.chat").await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the ``TcpStream``.
|
||||
pub async fn admin(self, target: &str) -> Result<(), Error> {
|
||||
self.tx
|
||||
.clone()
|
||||
.write(format!("ADMIN {}\r\n", target))
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set the status of the client.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.away("afk").await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the ``TcpStream``.
|
||||
pub async fn away(self, message: &str) -> Result<(), Error> {
|
||||
self.tx
|
||||
.clone()
|
||||
.write(format!("AWAY {}\r\n", message))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub async fn cap_mode(self, mode: CapMode) -> Result<(), Error> {
|
||||
let cap_mode = match mode {
|
||||
CapMode::LS => "CAP LS 302\r\n",
|
||||
CapMode::END => "CAP END\r\n",
|
||||
};
|
||||
self.tx.clone().write(cap_mode.to_string()).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Invite someone to a channel.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.invite("liblemonirc", "#async-circe").await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the ``TcpStream``.
|
||||
pub async fn invite(self, username: &str, channel: &str) -> Result<(), Error> {
|
||||
self.tx
|
||||
.clone()
|
||||
.write(format!("INVITE {} {}\r\n", username, channel))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Join a channel.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.join("#chaos").await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the ``TcpStream``.
|
||||
pub async fn join(self, channel: &str) -> Result<(), Error> {
|
||||
self.tx
|
||||
.clone()
|
||||
.write(format!("JOIN {}\r\n", channel))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// List available channels on an IRC, or users in a channel.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.list(None, None).await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the ``TcpStream``.
|
||||
pub async fn list(self, channel: Option<&str>, server: Option<&str>) -> Result<(), Error> {
|
||||
let mut formatted = "LIST".to_string();
|
||||
if let Some(channel) = channel {
|
||||
formatted.push_str(format!(" {}", channel).as_str());
|
||||
}
|
||||
if let Some(server) = server {
|
||||
formatted.push_str(format!(" {}", server).as_str());
|
||||
}
|
||||
formatted.push_str("\r\n");
|
||||
self.tx.clone().write(formatted).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set the mode for a user.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.mode("test", Some("+B")).await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the ``TcpStream``.
|
||||
pub async fn mode(self, target: &str, mode: Option<&str>) -> Result<(), Error> {
|
||||
if let Some(mode) = mode {
|
||||
self.tx
|
||||
.clone()
|
||||
.write(format!("MODE {} {}\r\n", target, mode,))
|
||||
.await?;
|
||||
} else {
|
||||
self.tx
|
||||
.clone()
|
||||
.write(format!("MODE {}\r\n", target))
|
||||
.await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get all the people online in channels.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.names("#chaos,#async-circe", None).await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the ``TcpStream``.
|
||||
pub async fn names(self, channel: &str, server: Option<&str>) -> Result<(), Error> {
|
||||
if let Some(server) = server {
|
||||
self.tx
|
||||
.clone()
|
||||
.write(format!("NAMES {} {}\r\n", channel, server))
|
||||
.await?;
|
||||
} else {
|
||||
self.tx
|
||||
.clone()
|
||||
.write(format!("NAMES {}\r\n", channel))
|
||||
.await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Change your nickname on a server.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.nick("Not async-circe").await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the ``TcpStream``.
|
||||
pub async fn nick(self, nickname: &str) -> Result<(), Error> {
|
||||
self.tx
|
||||
.clone()
|
||||
.write(format!("NICK {}\r\n", nickname))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Authentificate as an operator on a server.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.oper("username", "password").await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the ``TcpStream``.
|
||||
pub async fn oper(self, username: &str, password: &str) -> Result<(), Error> {
|
||||
self.tx
|
||||
.clone()
|
||||
.write(format!("OPER {} {}\r\n", username, password))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Leave a channel.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.part("#chaos").await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the ``TcpStream``.
|
||||
pub async fn part(self, channel: &str) -> Result<(), Error> {
|
||||
self.tx
|
||||
.clone()
|
||||
.write(format!("PART {}\r\n", channel))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub async fn pass(self, password: &str) -> Result<(), Error> {
|
||||
self.tx
|
||||
.clone()
|
||||
.write(format!("PASS {}\r\n", password))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Tests the presence of a connection to a server.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.ping("libera.chat", None).await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the ``TcpStream``.
|
||||
pub async fn ping(self, server1: &str, server2: Option<&str>) -> Result<(), Error> {
|
||||
if let Some(server2) = server2 {
|
||||
self.tx
|
||||
.clone()
|
||||
.write(format!("PING {} {}\r\n", server1, server2))
|
||||
.await?;
|
||||
} else {
|
||||
self.tx
|
||||
.clone()
|
||||
.write(format!("PING {}\r\n", server1))
|
||||
.await?;
|
||||
}
|
||||
// TODO look if we actually get a PONG back
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub async fn pong(self, ping: &str) -> Result<(), Error> {
|
||||
self.tx.clone().write(format!("PONG {}\r\n", ping)).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Send a message to a channel.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.privmsg("#chaos", "Hello").await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the ``TcpStream``.
|
||||
pub async fn privmsg(self, channel: &str, message: &str) -> Result<(), Error> {
|
||||
self.tx
|
||||
.clone()
|
||||
.write(format!("PRIVMSG {} :{}\r\n", channel, message))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Leave the IRC server you are connected to.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # use async_circe::*;
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.quit(None).await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the ``TcpStream``.
|
||||
pub async fn quit(self, recv: Read, message: Option<&str>) -> Result<(), Error> {
|
||||
if let Some(message) = message {
|
||||
self.tx
|
||||
.clone()
|
||||
.write(format!("QUIT :{}\r\n", message))
|
||||
.await?;
|
||||
} else {
|
||||
self.tx
|
||||
.clone()
|
||||
.write(format!(
|
||||
"QUIT :async-circe {} (https://crates.io/crates/async-circe)\r\n",
|
||||
env!("CARGO_PKG_VERSION")
|
||||
))
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get the topic of a channel.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # use async_circe::*;
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.topic("#chaos", None).await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// Set the topic of a channel.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.topic("#chaos", Some("CHAOS")).await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the ``TcpStream``.
|
||||
pub async fn topic(self, channel: &str, topic: Option<&str>) -> Result<(), Error> {
|
||||
if let Some(topic) = topic {
|
||||
self.tx
|
||||
.clone()
|
||||
.write(format!("TOPIC {} :{}\r\n", channel, topic))
|
||||
.await?;
|
||||
} else {
|
||||
self.tx
|
||||
.clone()
|
||||
.write(format!("TOPIC {}\r\n", channel))
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub async fn user(
|
||||
self,
|
||||
username: String,
|
||||
s1: &str,
|
||||
s2: &str,
|
||||
realname: String,
|
||||
) -> Result<(), Error> {
|
||||
self.tx
|
||||
.clone()
|
||||
.write(format!("USER {} {} {} :{}\r\n", username, s1, s2, realname))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
274
src/commands.rs
274
src/commands.rs
|
@ -1,274 +0,0 @@
|
|||
//! IRC commands
|
||||
//! - commands that can be recived from a server
|
||||
//! - commands that can be send to the server
|
||||
|
||||
#[doc(hidden)]
|
||||
#[derive(Debug)]
|
||||
pub enum CapMode {
|
||||
LS,
|
||||
END,
|
||||
}
|
||||
|
||||
/// Commands that can be send or recived from an IRC server.
|
||||
#[derive(Debug)]
|
||||
pub enum Command {
|
||||
// TODO:
|
||||
// SERVICE <nickname> <reserved> <distribution> <type> <reserved> <info>
|
||||
// SQUIT <server> <comment>
|
||||
//
|
||||
/// Request information about the admin of a given server.
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.admin("libera.chat").await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the TcpStream.
|
||||
ADMIN(
|
||||
/// Target
|
||||
String,
|
||||
),
|
||||
/// Set the status of the client.
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.away("afk").await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
AWAY(
|
||||
/// Message
|
||||
String,
|
||||
),
|
||||
#[doc(hidden)]
|
||||
CAP(CapMode),
|
||||
/// Invite someone to a channel.
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.invite("liblemonirc", "#async-circe").await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
INVITE(
|
||||
/// User
|
||||
String,
|
||||
/// Channel
|
||||
String,
|
||||
),
|
||||
/// Join a channel.
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.join("#chaos").await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
JOIN(
|
||||
/// Channel
|
||||
String,
|
||||
),
|
||||
/// List available channels on an IRC, or users in a channel.
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.list(None, None).await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
LIST(
|
||||
/// Channel
|
||||
Option<String>,
|
||||
/// Server to foreward request to
|
||||
Option<String>,
|
||||
),
|
||||
/// Set the mode for a user.
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.mode("test", Some("+B")).await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
MODE(
|
||||
/// Channel
|
||||
String,
|
||||
/// Mode
|
||||
Option<String>,
|
||||
),
|
||||
/// Get all the people online in channels.
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.names("#chaos,#async-circe", None).await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
NAMES(
|
||||
/// Channel
|
||||
String,
|
||||
/// User
|
||||
String,
|
||||
),
|
||||
/// Change your nickname on a server.
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.nick("Not async-circe").await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
NICK(
|
||||
/// Nickname
|
||||
String,
|
||||
),
|
||||
/// Authentificate as an operator on a server.
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.oper("username", "password").await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
OPER(
|
||||
/// Username
|
||||
String,
|
||||
/// Password
|
||||
String,
|
||||
),
|
||||
/// Everything that is not a command
|
||||
OTHER(String),
|
||||
/// Leave a channel.
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.part("#chaos").await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
PART(
|
||||
/// Target
|
||||
String,
|
||||
),
|
||||
#[doc(hidden)]
|
||||
PASS(String),
|
||||
/// Tests the presence of a connection to a server.
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.ping("libera.chat", None).await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
PING(String),
|
||||
#[doc(hidden)]
|
||||
PONG(String, String),
|
||||
/// Message send in a channel
|
||||
PRIVMSG(
|
||||
/// Source Nickname
|
||||
String,
|
||||
/// Channel
|
||||
String,
|
||||
/// Message
|
||||
String,
|
||||
),
|
||||
/// Leave the IRC server you are connected to.
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.quit(None).await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
QUIT(
|
||||
/// Leave message
|
||||
String,
|
||||
),
|
||||
/// Get the topic of a channel.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.topic("#chaos", None).await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// Set the topic of a channel.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.topic("#chaos", Some("main channel")).await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the TcpStream.
|
||||
TOPIC(
|
||||
/// Channel
|
||||
String,
|
||||
/// Topic
|
||||
String,
|
||||
),
|
||||
/// User the set the topic in a channel at a time
|
||||
TOPIC_BY(String, String),
|
||||
#[doc(hidden)]
|
||||
USER(String, String, String, String),
|
||||
}
|
||||
|
||||
impl Command {
|
||||
/// Creates a Command from a `&str`. Currently `[PRIVMSG]` `[TOPIC]` `[NAMES]` and `[PONG]` are supported.
|
||||
///
|
||||
/// # Panics
|
||||
/// This function will panic if the ``IRCd`` sends malformed messages. Please contact the
|
||||
/// maintainer of your ``IRCd`` if this happens.
|
||||
pub async fn command_from_str(s: String) -> Self {
|
||||
let new = s.trim();
|
||||
tracing::trace!("{}", new);
|
||||
let parts: Vec<&str> = new.split_whitespace().collect();
|
||||
|
||||
if parts.get(0) == Some(&"PING") {
|
||||
return Self::PING(parts[1].to_string());
|
||||
}
|
||||
|
||||
match parts.get(1) {
|
||||
Some(&"PRIVMSG") => {
|
||||
let nick_realname = parts[0];
|
||||
let nick: String;
|
||||
|
||||
let index = nick_realname.chars().position(|c| c == '!');
|
||||
if let Some(index) = index {
|
||||
if index > 0 {
|
||||
nick = (nick_realname[1..index]).to_string();
|
||||
} else {
|
||||
nick = String::new();
|
||||
}
|
||||
} else {
|
||||
nick = String::new();
|
||||
}
|
||||
|
||||
let msg = parts[3..].join(" ");
|
||||
|
||||
Self::PRIVMSG(nick, parts[2].to_string(), (msg[1..]).to_string())
|
||||
}
|
||||
Some(&"331") | Some(&"332") => {
|
||||
let topic = parts[4..].join(" ");
|
||||
Self::TOPIC(parts[3].to_string(), (topic[1..]).to_string())
|
||||
}
|
||||
Some(&"333") => {
|
||||
Self::TOPIC_BY(parts[4].to_string(), parts[5].to_string())
|
||||
}
|
||||
Some(&"353") => {
|
||||
let user = parts[5..].join(" ");
|
||||
Self::NAMES(parts[4].to_string(), (user[1..]).to_string())
|
||||
}
|
||||
Some(&"PONG") => {
|
||||
let server = parts[3];
|
||||
Self::PONG(parts[2].to_string(), (server[1..]).to_string())
|
||||
}
|
||||
_ => Self::OTHER(new.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
1
src/commands/mod.rs
Normal file
1
src/commands/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub mod parser;
|
82
src/commands/parser.rs
Normal file
82
src/commands/parser.rs
Normal file
|
@ -0,0 +1,82 @@
|
|||
#[doc(hidden)]
|
||||
#[derive(Debug)]
|
||||
pub enum CapMode {
|
||||
LS,
|
||||
END,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Command {
|
||||
ADMIN(String),
|
||||
AWAY(String),
|
||||
#[doc(hidden)]
|
||||
CAP(CapMode),
|
||||
INVITE(String, String),
|
||||
JOIN(String),
|
||||
LIST(Option<String>, Option<String>),
|
||||
MODE(String, Option<String>),
|
||||
NAMES(String, String),
|
||||
NICK(String),
|
||||
OPER(String, String),
|
||||
OTHER(String),
|
||||
PART(String),
|
||||
#[doc(hidden)]
|
||||
PASS(String),
|
||||
PING(String),
|
||||
#[doc(hidden)]
|
||||
PONG(String, String),
|
||||
PRIVMSG(String, String, String),
|
||||
QUIT(String),
|
||||
TOPIC(String, String),
|
||||
TOPIC_BY(String, String),
|
||||
#[doc(hidden)]
|
||||
USER(String, String, String, String),
|
||||
}
|
||||
|
||||
impl Command {
|
||||
pub async fn command_from_str(s: String) -> Self {
|
||||
let new = s.trim();
|
||||
tracing::trace!("{}", new);
|
||||
|
||||
let parts: Vec<&str> = new.split_whitespace().collect();
|
||||
if parts.get(0) == Some(&"PING") {
|
||||
return Self::PING(parts[1].to_string());
|
||||
}
|
||||
|
||||
match parts.get(1) {
|
||||
Some(&"PRIVMSG") => {
|
||||
let nick_realname = parts[0];
|
||||
let nick: String;
|
||||
|
||||
let index = nick_realname.chars().position(|c| c == '!');
|
||||
if let Some(index) = index {
|
||||
if index > 0 {
|
||||
nick = (nick_realname[1..index]).to_string();
|
||||
} else {
|
||||
nick = String::new();
|
||||
}
|
||||
} else {
|
||||
nick = String::new();
|
||||
}
|
||||
|
||||
let msg = parts[3..].join(" ");
|
||||
|
||||
Self::PRIVMSG(nick, parts[2].to_string(), (msg[1..]).to_string())
|
||||
}
|
||||
Some(&("331" | "332")) => {
|
||||
let topic = parts[4..].join(" ");
|
||||
Self::TOPIC(parts[3].to_string(), (topic[1..]).to_string())
|
||||
}
|
||||
Some(&"333") => Self::TOPIC_BY(parts[4].to_string(), parts[5].to_string()),
|
||||
Some(&"353") => {
|
||||
let user = parts[5..].join(" ");
|
||||
Self::NAMES(parts[4].to_string(), (user[1..]).to_string())
|
||||
}
|
||||
Some(&"PONG") => {
|
||||
let server = parts[3];
|
||||
Self::PONG(parts[2].to_string(), (server[1..]).to_string())
|
||||
}
|
||||
_ => Self::OTHER(new.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
692
src/lib.rs
692
src/lib.rs
|
@ -1,690 +1,6 @@
|
|||
//! A simple IRC crate written in rust
|
||||
//! ```run_fut
|
||||
//! use async_circe::{commands::Command, Client, Config};
|
||||
//!
|
||||
//! #[tokio::main(flavor = "current_thread")]
|
||||
//! async fn main() -> Result<(), tokio::io::Error> {
|
||||
//! let config = Config::default();
|
||||
//! let mut client = Client::new(config).await.unwrap();
|
||||
//! client.identify().await.unwrap();
|
||||
//!
|
||||
//! loop {
|
||||
//! if let Some(command) = client.read().await? {
|
||||
//! if let Command::PRIVMSG(nick, channel, message) = command {
|
||||
//! println!("{} in {}: {}", nick, channel, message);
|
||||
//! }
|
||||
//! }
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! The crate requires `tokio` with the `macros` and `rt` feature enabled to function.<br>
|
||||
//! For more examples (connecting to IRCs that dont use SSL, getting the config from
|
||||
//! a toml file, debugging or just in general an overview how a project with async-circe
|
||||
//! is structured) see the [examples](https://git.karx.xyz/circe/async-circe/src/branch/master/examples) folder on our git.
|
||||
|
||||
#![warn(missing_docs)] // We want everything documented
|
||||
#![allow(clippy::needless_return, non_camel_case_types)] // Wants to remove a return statement, but when it's removed the code doesn't compile
|
||||
#![feature(doc_cfg)]
|
||||
|
||||
use tokio::io::BufReader;
|
||||
use tokio::io::Error;
|
||||
use tokio::io::{AsyncBufReadExt, AsyncWriteExt};
|
||||
use tokio::net::TcpStream;
|
||||
|
||||
#[cfg(feature = "tls")]
|
||||
use native_tls::TlsConnector;
|
||||
|
||||
#[cfg(feature = "toml_config")]
|
||||
use serde_derive::Deserialize;
|
||||
#[cfg(feature = "toml_config")]
|
||||
use std::fs::File;
|
||||
#[cfg(feature = "toml_config")]
|
||||
use std::io::Read;
|
||||
#[cfg(any(doc, feature = "toml_config"))]
|
||||
use std::path::Path;
|
||||
#[cfg(feature = "toml_config")]
|
||||
use tokio::io::ErrorKind;
|
||||
#![allow(non_camel_case_types)]
|
||||
#![feature(destructuring_assignment)]
|
||||
|
||||
pub mod client;
|
||||
pub mod commands;
|
||||
|
||||
/// An IRC client
|
||||
pub struct Client {
|
||||
config: Config,
|
||||
#[cfg(not(feature = "tls"))]
|
||||
buf_reader: BufReader<TcpStream>,
|
||||
#[cfg(feature = "tls")]
|
||||
buf_reader: BufReader<tokio_native_tls::TlsStream<tokio::net::TcpStream>>,
|
||||
}
|
||||
|
||||
/// Config for the IRC client<br>
|
||||
/// For more information about what arguments the IRC commands take, see [`commands::Command`].
|
||||
#[derive(Clone, Debug, Default)]
|
||||
#[cfg_attr(feature = "toml_config", derive(Deserialize))]
|
||||
pub struct Config {
|
||||
channels: Vec<String>,
|
||||
host: String,
|
||||
mode: Option<String>,
|
||||
nickname: Option<String>,
|
||||
port: u16,
|
||||
username: String,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
/// Creates a new client with a given [`Config`].
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// let mut client = Client::new(config).await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns error if the client could not connect to the host.
|
||||
/// # Panics
|
||||
/// Panics if the client can't connect to the given host.
|
||||
pub async fn new(config: Config) -> Result<Self, Error> {
|
||||
tracing::debug!("Creating TcpStream");
|
||||
let stream = TcpStream::connect(format!("{}:{}", config.host, config.port))
|
||||
.await
|
||||
.unwrap();
|
||||
tracing::debug!("New TcpStream created");
|
||||
|
||||
#[cfg(feature = "tls")]
|
||||
{
|
||||
let connector = TlsConnector::builder().build().unwrap();
|
||||
let async_connector = tokio_native_tls::TlsConnector::from(connector);
|
||||
|
||||
let sslstream = async_connector
|
||||
.connect(config.host.as_str(), stream)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let buf_reader = BufReader::new(sslstream);
|
||||
|
||||
return Ok(Self { config, buf_reader });
|
||||
};
|
||||
|
||||
#[cfg(not(feature = "tls"))]
|
||||
{
|
||||
let buf_reader = BufReader::new(stream);
|
||||
return Ok(Self { config, buf_reader });
|
||||
};
|
||||
}
|
||||
|
||||
/// Identify user and joins the in the [`Config`] specified channels.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// client.identify().await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns error if the client could not write to the stream.
|
||||
pub async fn identify(&mut self) -> Result<(), Error> {
|
||||
self.cap_mode(commands::CapMode::LS).await?;
|
||||
self.cap_mode(commands::CapMode::END).await?;
|
||||
|
||||
self.user(
|
||||
self.config.username.clone(),
|
||||
"*",
|
||||
"*",
|
||||
self.config.username.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
if let Some(nick) = self.config.nickname.clone() {
|
||||
self.nick(&nick).await?;
|
||||
} else {
|
||||
self.nick(&self.config.username.clone()).await?;
|
||||
}
|
||||
|
||||
loop {
|
||||
if let Some(command) = self.read().await? {
|
||||
match command {
|
||||
commands::Command::PING(code) => {
|
||||
self.pong(&code).await?;
|
||||
}
|
||||
commands::Command::OTHER(line) => {
|
||||
tracing::trace!("{}", line);
|
||||
if line.contains("001") {
|
||||
break;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let config = self.config.clone();
|
||||
let user = {
|
||||
if let Some(nick) = config.nickname {
|
||||
nick
|
||||
} else {
|
||||
config.username
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(mode) = config.mode {
|
||||
self.mode(&user, Some(&mode)).await?;
|
||||
}
|
||||
|
||||
for channel in &config.channels {
|
||||
self.join(channel).await?;
|
||||
}
|
||||
|
||||
tracing::info!("async-circe has identified");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn read_string(&mut self) -> Result<Option<String>, tokio::io::Error> {
|
||||
let mut buffer = String::new();
|
||||
|
||||
let num_bytes = match self.buf_reader.read_line(&mut buffer).await {
|
||||
Ok(b) => b,
|
||||
Err(e) => {
|
||||
tracing::error!("{}", e);
|
||||
return Err(e);
|
||||
}
|
||||
};
|
||||
|
||||
if num_bytes == 0 {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
Ok(Some(buffer))
|
||||
}
|
||||
|
||||
/// Read data coming from the IRC as a [`commands::Command`].
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # use async_circe::*;
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// loop {
|
||||
/// if let Some(ref command) = client.read().await? {
|
||||
/// if let commands::Command::PRIVMSG(nick, channel, message) = command {
|
||||
/// println!("{} in {}: {}", nick, channel, message);
|
||||
/// }
|
||||
/// }
|
||||
/// # break;
|
||||
/// }
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the TcpStream.
|
||||
pub async fn read(&mut self) -> Result<Option<commands::Command>, tokio::io::Error> {
|
||||
if let Some(string) = self.read_string().await? {
|
||||
let command = commands::Command::command_from_str(string).await;
|
||||
|
||||
if let commands::Command::PING(command) = command {
|
||||
if let Err(_e) = self.pong(&command).await {
|
||||
return Ok(None);
|
||||
}
|
||||
return Ok(Some(commands::Command::PING("".to_string())));
|
||||
}
|
||||
return Ok(Some(command));
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
async fn write(&mut self, data: String) -> Result<(), Error> {
|
||||
tracing::trace!("{:?}", data);
|
||||
self.buf_reader.write_all(data.as_bytes()).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Request information about the admin of a given server.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # use async_circe::*;
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.admin("libera.chat").await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the TcpStream.
|
||||
pub async fn admin(&mut self, target: &str) -> Result<(), Error> {
|
||||
self.write(format!("ADMIN {}\r\n", target)).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set the status of the client.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.away("afk").await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the TcpStream.
|
||||
pub async fn away(&mut self, message: &str) -> Result<(), Error> {
|
||||
self.write(format!("AWAY {}\r\n", message)).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub async fn cap_mode(&mut self, mode: commands::CapMode) -> Result<(), Error> {
|
||||
let cap_mode = match mode {
|
||||
commands::CapMode::LS => "CAP LS 302\r\n",
|
||||
commands::CapMode::END => "CAP END\r\n",
|
||||
};
|
||||
self.write(cap_mode.to_string()).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Invite someone to a channel.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.invite("liblemonirc", "#async-circe").await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the TcpStream.
|
||||
pub async fn invite(&mut self, username: &str, channel: &str) -> Result<(), Error> {
|
||||
self.write(format!("INVITE {} {}\r\n", username, channel))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Join a channel.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.join("#chaos").await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the TcpStream.
|
||||
pub async fn join(&mut self, channel: &str) -> Result<(), Error> {
|
||||
self.write(format!("JOIN {}\r\n", channel)).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// List available channels on an IRC, or users in a channel.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.list(None, None).await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the TcpStream.
|
||||
pub async fn list(&mut self, channel: Option<&str>, server: Option<&str>) -> Result<(), Error> {
|
||||
let mut formatted = "LIST".to_string();
|
||||
if let Some(channel) = channel {
|
||||
formatted.push_str(format!(" {}", channel).as_str());
|
||||
}
|
||||
if let Some(server) = server {
|
||||
formatted.push_str(format!(" {}", server).as_str());
|
||||
}
|
||||
formatted.push_str("\r\n");
|
||||
self.write(formatted).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set the mode for a user.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.mode("test", Some("+B")).await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the TcpStream.
|
||||
pub async fn mode(&mut self, target: &str, mode: Option<&str>) -> Result<(), Error> {
|
||||
if let Some(mode) = mode {
|
||||
self.write(format!("MODE {} {}\r\n", target, mode,)).await?;
|
||||
} else {
|
||||
self.write(format!("MODE {}\r\n", target)).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get all the people online in channels.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.names("#chaos,#async-circe", None).await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the TcpStream.
|
||||
pub async fn names(&mut self, channel: &str, server: Option<&str>) -> Result<(), Error> {
|
||||
if let Some(server) = server {
|
||||
self.write(format!("NAMES {} {}\r\n", channel, server))
|
||||
.await?;
|
||||
} else {
|
||||
self.write(format!("NAMES {}\r\n", channel)).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Change your nickname on a server.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.nick("Not async-circe").await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the TcpStream.
|
||||
pub async fn nick(&mut self, nickname: &str) -> Result<(), Error> {
|
||||
self.write(format!("NICK {}\r\n", nickname)).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Authentificate as an operator on a server.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.oper("username", "password").await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the TcpStream.
|
||||
pub async fn oper(&mut self, username: &str, password: &str) -> Result<(), Error> {
|
||||
self.write(format!("OPER {} {}\r\n", username, password))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Leave a channel.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.part("#chaos").await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the TcpStream.
|
||||
pub async fn part(&mut self, channel: &str) -> Result<(), Error> {
|
||||
self.write(format!("PART {}\r\n", channel)).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub async fn pass(&mut self, password: &str) -> Result<(), Error> {
|
||||
self.write(format!("PASS {}\r\n", password)).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Tests the presence of a connection to a server.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.ping("libera.chat", None).await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the TcpStream.
|
||||
pub async fn ping(&mut self, server1: &str, server2: Option<&str>) -> Result<(), Error> {
|
||||
if let Some(server2) = server2 {
|
||||
self.write(format!("PING {} {}\r\n", server1, server2))
|
||||
.await?;
|
||||
} else {
|
||||
self.write(format!("PING {}\r\n", server1)).await?;
|
||||
}
|
||||
// TODO look if we actually get a PONG back
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub async fn pong(&mut self, ping: &str) -> Result<(), Error> {
|
||||
self.write(format!("PONG {}\r\n", ping)).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Send a message to a channel.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.privmsg("#chaos", "Hello").await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the TcpStream.
|
||||
pub async fn privmsg(&mut self, channel: &str, message: &str) -> Result<(), Error> {
|
||||
self.write(format!("PRIVMSG {} :{}\r\n", channel, message))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Leave the IRC server you are connected to.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # use async_circe::*;
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.quit(None).await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the TcpStream.
|
||||
pub async fn quit(&mut self, message: Option<&str>) -> Result<(), Error> {
|
||||
if let Some(message) = message {
|
||||
self.write(format!("QUIT :{}\r\n", message)).await?;
|
||||
} else {
|
||||
self.write(format!(
|
||||
"QUIT :async-circe {} (https://crates.io/crates/async-circe)\r\n",
|
||||
env!("CARGO_PKG_VERSION")
|
||||
))
|
||||
.await?;
|
||||
}
|
||||
tracing::info!("async-circe shutting down");
|
||||
self.buf_reader.shutdown().await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get the topic of a channel.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # use async_circe::*;
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.topic("#chaos", None).await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// Set the topic of a channel.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # let config = Default::default();
|
||||
/// # let mut client = Client::new(config).await?;
|
||||
/// # client.identify().await?;
|
||||
/// client.topic("#chaos", Some("CHAOS")).await?;
|
||||
/// # Ok(())
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns IO errors from the TcpStream.
|
||||
pub async fn topic(&mut self, channel: &str, topic: Option<&str>) -> Result<(), Error> {
|
||||
if let Some(topic) = topic {
|
||||
self.write(format!("TOPIC {} :{}\r\n", channel, topic))
|
||||
.await?;
|
||||
} else {
|
||||
self.write(format!("TOPIC {}\r\n", channel)).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub async fn user(
|
||||
&mut self,
|
||||
username: String,
|
||||
s1: &str,
|
||||
s2: &str,
|
||||
realname: String,
|
||||
) -> Result<(), Error> {
|
||||
self.write(format!("USER {} {} {} :{}\r\n", username, s1, s2, realname))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Config {
|
||||
/// Create a new config for the client
|
||||
/// # Example
|
||||
/// ```rust
|
||||
/// # use async_circe::Config;
|
||||
/// let config = Config::new(
|
||||
/// &["#chaos", "#async-circe"],
|
||||
/// "karx.xyz",
|
||||
/// Some("+B"),
|
||||
/// Some("async-circe"),
|
||||
/// 6697,
|
||||
/// "circe",
|
||||
/// );
|
||||
/// ```
|
||||
#[must_use]
|
||||
pub fn new(
|
||||
channels: &[&'static str],
|
||||
host: &str,
|
||||
mode: Option<&'static str>,
|
||||
nickname: Option<&'static str>,
|
||||
port: u16,
|
||||
username: &str,
|
||||
) -> Self {
|
||||
tracing::info!("New async-circe client config");
|
||||
// Conversion from &'static str to String
|
||||
let channels_config = channels
|
||||
.iter()
|
||||
.map(|channel| (*channel).to_string())
|
||||
.collect();
|
||||
|
||||
let mode_config: Option<String>;
|
||||
if let Some(mode) = mode {
|
||||
mode_config = Some(mode.to_string());
|
||||
} else {
|
||||
mode_config = None;
|
||||
}
|
||||
|
||||
let nickname_config: Option<String>;
|
||||
if let Some(nickname) = nickname {
|
||||
nickname_config = Some(nickname.to_string());
|
||||
} else {
|
||||
nickname_config = Some(username.to_string());
|
||||
}
|
||||
|
||||
let config = Self {
|
||||
channels: channels_config,
|
||||
host: host.into(),
|
||||
mode: mode_config,
|
||||
nickname: nickname_config,
|
||||
port,
|
||||
username: username.into(),
|
||||
};
|
||||
|
||||
tracing::debug!("async-circe config: {:?}", config);
|
||||
config
|
||||
}
|
||||
|
||||
/// Allows for configuring async-circe at runtime.
|
||||
/// # Example
|
||||
/// ```run_fut
|
||||
/// # use async_circe::Config;
|
||||
/// let config = Config::runtime_config(
|
||||
/// vec!["#chaos".to_string(), "#async-circe".to_string()],
|
||||
/// "karx.xyz".to_string(),
|
||||
/// Some("+B".to_string()),
|
||||
/// Some("async-circe".to_string()),
|
||||
/// 6697,
|
||||
/// "circe".to_string(),
|
||||
/// );
|
||||
/// ```
|
||||
#[must_use]
|
||||
pub fn runtime_config(
|
||||
channels: Vec<String>,
|
||||
host: String,
|
||||
mode: Option<String>,
|
||||
nickname: Option<String>,
|
||||
port: u16,
|
||||
username: String,
|
||||
) -> Self {
|
||||
tracing::info!("New async-circe client config");
|
||||
let mode_config: Option<String>;
|
||||
if let Some(mode) = mode {
|
||||
mode_config = Some(mode);
|
||||
} else {
|
||||
mode_config = None;
|
||||
}
|
||||
|
||||
let nickname_config: Option<String>;
|
||||
if let Some(nickname) = nickname {
|
||||
nickname_config = Some(nickname);
|
||||
} else {
|
||||
nickname_config = Some(username.to_string());
|
||||
}
|
||||
|
||||
let config = Self {
|
||||
channels,
|
||||
host,
|
||||
mode: mode_config,
|
||||
nickname: nickname_config,
|
||||
port,
|
||||
username,
|
||||
};
|
||||
|
||||
tracing::debug!("async-circe config: {:?}", config);
|
||||
config
|
||||
}
|
||||
|
||||
/// Create a config from a toml file
|
||||
/// # Example
|
||||
/// ```toml
|
||||
/// #Config.toml
|
||||
/// channels = ["#chaos", "#async-circe"]
|
||||
/// host = "karx.xyz"
|
||||
/// mode = "+B"
|
||||
/// nickname = "async-circe"
|
||||
/// port = 6667
|
||||
/// username = "circe"
|
||||
/// ```
|
||||
/// ```run_fut
|
||||
/// let config = Config::from_toml("Config.toml")?;
|
||||
/// ```
|
||||
/// # Errors
|
||||
/// Returns an Error if the file cannot be opened or if the TOML is invalid
|
||||
#[cfg(any(doc, feature = "toml_config"))]
|
||||
#[doc(cfg(feature = "toml_config"))]
|
||||
pub fn from_toml<P: AsRef<Path>>(path: P) -> Result<Self, Error> {
|
||||
tracing::info!("New async-circe client config");
|
||||
let mut file = File::open(&path)?;
|
||||
let mut data = String::new();
|
||||
file.read_to_string(&mut data)?;
|
||||
|
||||
let config = toml::from_str(&data)
|
||||
.map_err(|e| Error::new(ErrorKind::Other, format!("Invalid TOML: {}", e)));
|
||||
tracing::debug!("async-circe config: {:?}", config);
|
||||
config
|
||||
}
|
||||
}
|
||||
pub mod stream;
|
||||
|
|
2
src/stream/mod.rs
Normal file
2
src/stream/mod.rs
Normal file
|
@ -0,0 +1,2 @@
|
|||
pub mod read;
|
||||
pub mod write;
|
45
src/stream/read.rs
Normal file
45
src/stream/read.rs
Normal file
|
@ -0,0 +1,45 @@
|
|||
use crate::commands::parser::Command;
|
||||
|
||||
use tokio::io::{AsyncBufReadExt, BufReader, Error, ReadHalf};
|
||||
use tokio::net::TcpStream;
|
||||
|
||||
#[cfg(feature = "tls")]
|
||||
use tokio_rustls::client::TlsStream;
|
||||
|
||||
pub struct Read {
|
||||
#[cfg(feature = "tls")]
|
||||
pub recv: BufReader<ReadHalf<TlsStream<TcpStream>>>,
|
||||
#[cfg(not(feature = "tls"))]
|
||||
pub recv: BufReader<ReadHalf<TcpStream>>,
|
||||
}
|
||||
|
||||
impl Read {
|
||||
#[must_use]
|
||||
#[cfg(feature = "tls")]
|
||||
pub fn new(recv: BufReader<ReadHalf<TlsStream<TcpStream>>>) -> Self {
|
||||
Self { recv }
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
#[cfg(not(feature = "tls"))]
|
||||
pub fn new(recv: BufReader<ReadHalf<TcpStream>>) -> Self {
|
||||
Self { recv }
|
||||
}
|
||||
|
||||
/// # Errors
|
||||
/// Returns errors from the ``TcpStream``.
|
||||
pub async fn read(&mut self) -> Result<Option<Command>, Error> {
|
||||
let mut buf = String::new();
|
||||
let bytes = match self.recv.read_line(&mut buf).await {
|
||||
Ok(b) => b,
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
|
||||
if bytes == 0 {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let command = Command::command_from_str(buf).await;
|
||||
Ok(Some(command))
|
||||
}
|
||||
}
|
39
src/stream/write.rs
Normal file
39
src/stream/write.rs
Normal file
|
@ -0,0 +1,39 @@
|
|||
use parking_lot::RwLock;
|
||||
use std::sync::Arc;
|
||||
use tokio::io::{AsyncWriteExt, Error, WriteHalf};
|
||||
use tokio::net::TcpStream;
|
||||
|
||||
#[cfg(feature = "tls")]
|
||||
use tokio_rustls::client::TlsStream;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Write {
|
||||
#[cfg(feature = "tls")]
|
||||
pub tx: Arc<RwLock<WriteHalf<TlsStream<TcpStream>>>>,
|
||||
#[cfg(not(feature = "tls"))]
|
||||
pub tx: Arc<RwLock<WriteHalf<TcpStream>>>,
|
||||
}
|
||||
|
||||
impl Write {
|
||||
#[cfg(not(feature = "tls"))]
|
||||
pub async fn new(tx: WriteHalf<TcpStream>) -> Self {
|
||||
Self {
|
||||
tx: Arc::new(RwLock::new(tx)),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "tls")]
|
||||
pub async fn new(tx: WriteHalf<TlsStream<TcpStream>>) -> Self {
|
||||
Self {
|
||||
tx: Arc::new(RwLock::new(tx)),
|
||||
}
|
||||
}
|
||||
|
||||
/// # Errors
|
||||
/// Returns errors from the ``TcpStream``.
|
||||
pub async fn write(self, buf: String) -> Result<(), Error> {
|
||||
tracing::trace!("{:?}", buf);
|
||||
self.tx.write().write_all(buf.as_bytes()).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue