diff options
author | Jannis M. Hoffmann <jannis@fehcom.de> | 2024-03-14 22:52:36 +0100 |
---|---|---|
committer | Jannis M. Hoffmann <jannis@fehcom.de> | 2024-03-14 22:52:36 +0100 |
commit | 80f3c54a9c33d27802bc59538932d163b00d9e95 (patch) | |
tree | cdbd94ff101fbe1d657aef02f9dd01cda5bc6506 | |
parent | 285fa4d40144c4c81fafe7865dfdf866b8ddf980 (diff) |
convert to protobuf
-rw-r--r-- | Cargo.lock | 361 | ||||
-rw-r--r-- | Cargo.toml | 17 | ||||
-rw-r--r-- | build.rs | 11 | ||||
-rw-r--r-- | jwebmail.proto | 156 | ||||
-rw-r--r-- | src/arguments.rs | 123 | ||||
-rw-r--r-- | src/cmd.rs | 89 | ||||
-rw-r--r-- | src/cmd/count.rs | 44 | ||||
-rw-r--r-- | src/cmd/folders.rs | 15 | ||||
-rw-r--r-- | src/cmd/list.rs | 116 | ||||
-rw-r--r-- | src/cmd/move_mail.rs | 18 | ||||
-rw-r--r-- | src/cmd/raw.rs | 153 | ||||
-rw-r--r-- | src/cmd/read.rs | 24 | ||||
-rw-r--r-- | src/cmd/remove.rs | 17 | ||||
-rw-r--r-- | src/error.rs | 32 | ||||
-rw-r--r-- | src/main.rs | 57 | ||||
-rw-r--r-- | src/pb3/jwebmail.rs | 3966 | ||||
-rw-r--r-- | src/pb3/mod.rs | 3 | ||||
-rw-r--r-- | src/rfc822.rs | 330 |
18 files changed, 4838 insertions, 694 deletions
@@ -3,6 +3,15 @@ version = 3 [[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] name = "android-tzdata" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -19,9 +28,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.5.0" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" dependencies = [ "anstyle", "anstyle-parse", @@ -52,20 +61,26 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "anstyle-wincon" -version = "2.1.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] +name = "anyhow" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" + +[[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -78,6 +93,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] +name = "bitflags" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" + +[[package]] name = "bumpalo" version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -119,14 +140,14 @@ dependencies = [ "js-sys", "num-traits", "wasm-bindgen", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] name = "clap" -version = "4.4.4" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136" +checksum = "b230ab84b0ffdf890d5a10abdbc8b83ae1c4918275daea1ab8801f71536b2651" dependencies = [ "clap_builder", "clap_derive", @@ -134,9 +155,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.4" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstream", "anstyle", @@ -146,9 +167,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.2" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" dependencies = [ "heck", "proc-macro2", @@ -158,9 +179,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.5.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "colorchoice" @@ -187,6 +208,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" [[package]] +name = "either" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" + +[[package]] name = "encoding_rs" version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -196,6 +223,22 @@ dependencies = [ ] [[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] name = "gethostname" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -206,12 +249,27 @@ dependencies = [ ] [[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] name = "heck" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] name = "iana-time-zone" version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -235,6 +293,16 @@ dependencies = [ ] [[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] name = "itoa" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -251,24 +319,31 @@ dependencies = [ [[package]] name = "jwebmail-extract" -version = "0.6.0" +version = "0.7.0" dependencies = [ + "anyhow", "chrono", "clap", "libc", "log", "maildir", "mailparse", - "serde", - "serde_json", + "protobuf", + "protobuf-codegen", "simplelog", ] [[package]] name = "libc" -version = "0.2.148" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "log" @@ -298,6 +373,12 @@ dependencies = [ ] [[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] name = "num-traits" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -323,14 +404,65 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] [[package]] +name = "protobuf" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58678a64de2fced2bdec6bca052a6716a0efe692d6e3f53d1bda6a1def64cfc0" +dependencies = [ + "once_cell", + "protobuf-support", + "thiserror", +] + +[[package]] +name = "protobuf-codegen" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32777b0b3f6538d9d2e012b3fad85c7e4b9244b5958d04a6415f4333782b7a77" +dependencies = [ + "anyhow", + "once_cell", + "protobuf", + "protobuf-parse", + "regex", + "tempfile", + "thiserror", +] + +[[package]] +name = "protobuf-parse" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96cb37955261126624a25b5e6bda40ae34cf3989d52a783087ca6091b29b5642" +dependencies = [ + "anyhow", + "indexmap", + "log", + "protobuf", + "protobuf-support", + "tempfile", + "thiserror", + "which", +] + +[[package]] +name = "protobuf-support" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1ed294a835b0f30810e13616b1cd34943c6d1e84a8f3b0dcfe466d256c3e7e7" +dependencies = [ + "thiserror", +] + +[[package]] name = "quote" version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -346,10 +478,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3866219251662ec3b26fc217e3e05bf9c4f84325234dfb96bf0bf840889e49" [[package]] -name = "ryu" -version = "1.0.15" +name = "regex" +version = "1.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "rustix" +version = "0.38.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] [[package]] name = "serde" @@ -372,17 +540,6 @@ dependencies = [ ] [[package]] -name = "serde_json" -version = "1.0.107" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] name = "simplelog" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -395,9 +552,9 @@ dependencies = [ [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" [[package]] name = "syn" @@ -411,6 +568,18 @@ dependencies = [ ] [[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] name = "termcolor" version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -420,6 +589,26 @@ dependencies = [ ] [[package]] +name = "thiserror" +version = "1.0.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e3de26b0965292219b4287ff031fcba86837900fe9cd2b34ea8ad893c0953d2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "268026685b2be38d7103e9e507c938a1fcb3d7e6eb15e87870b617bf37b6d581" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] name = "time" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -516,6 +705,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -552,7 +753,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -561,7 +762,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.4", ] [[package]] @@ -570,13 +780,28 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", ] [[package]] @@ -586,37 +811,79 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" + +[[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] +name = "windows_aarch64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" + +[[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] +name = "windows_i686_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + +[[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] +name = "windows_i686_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + +[[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] +name = "windows_x86_64_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + +[[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" + +[[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" @@ -1,9 +1,9 @@ [package] name = "jwebmail-extract" -version = "0.6.0" +version = "0.7.0" authors = ["Jannis M. Hoffmann <jannis@fehcom.de>"] edition = "2021" -rust-version = "1.70" +rust-version = "1.75" resolver = "2" [profile.release-small] @@ -16,13 +16,16 @@ codegen-units = 1 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[build-dependencies] +anyhow = "1.0" +protobuf-codegen = "3.4" + [dependencies] +chrono = "0.4" +clap = { version = "4.5", features = ["derive"] } libc = "0.2" +log = "0.4" maildir = "0.6" -serde_json = "1.0" -serde = { version = "1.0", features = ["derive"] } mailparse = "0.14" -chrono = "0.4" -clap = { version = "4.0", features = ["derive"] } -log = "0.4" +protobuf = "3.4" simplelog = "0.12" diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..e8ef3be --- /dev/null +++ b/build.rs @@ -0,0 +1,11 @@ +use anyhow::Result; +use protobuf_codegen::Codegen; + +fn main() -> Result<()> { + Codegen::new() + .protoc() + .include(".") + .input("jwebmail.proto") + .out_dir("src/pb3") + .run() +} diff --git a/jwebmail.proto b/jwebmail.proto new file mode 100644 index 0000000..bf1454a --- /dev/null +++ b/jwebmail.proto @@ -0,0 +1,156 @@ +syntax = "proto3"; + +package jwebmail; + +message MIMEHeader { + + enum ContentDisposition { + CONTENT_DISPOSITION_NONE = 0; + CONTENT_DISPOSITION_INLINE = 1; + CONTENT_DISPOSITION_ATTACHMENT = 2; + } + + string maintype = 1; + string subtype = 2; + ContentDisposition contentdispo = 3; + optional string file_name = 4; +} + +message MailHeader { + + message MailAddr { + optional string name = 1; + string address = 2; + } + + string send_date = 1; + repeated MailAddr written_from = 2; + optional MailAddr sender = 3; + repeated MailAddr reply_to = 4; + repeated MailAddr send_to = 5; + repeated MailAddr cc = 6; + repeated MailAddr bcc = 7; + string subject = 8; + repeated string comments = 9; + repeated string keywords = 10; + MIMEHeader mime = 11; +} + +message ListMailHeader { + uint64 byte_size = 1; + bool unread = 2; + string rec_date = 3; + string mid = 4; + MailHeader header = 5; +} + +message MailBody { + message Multipart { + optional string preamble = 1; + repeated MIMEPart parts = 2; + optional string epilogue = 3; + } + + oneof Body { + string discrete = 1; + Multipart multipart = 2; + Mail mail = 3; + } +} + +message Mail { + MailHeader head = 1; + MailBody body = 2; +} + +message MIMEPart { + MIMEHeader mime_header = 1; + MailBody body = 2; +} + +// Request-Response pairs + +message ListReq { + string folder = 1; + int32 start = 2; + int32 end = 3; + string sort = 4; +} + +message ListResp { + repeated ListMailHeader mail_heads = 1; +} + +message StatsReq { + string folder = 1; +} + +message StatsResp { + uint32 mail_count = 1; + uint32 unread_count = 2; + uint64 byte_size = 3; +} + +message ShowReq { + string folder = 1; + string mid = 2; +} + +message ShowResp { + Mail mail = 1; +} + +message RawReq { + string folder = 1; + string mid = 2; + optional string path = 3; +} + +message RawResp { + MIMEHeader header = 1; + bytes body = 2; +} + +message SearchReq { + string folder = 1; + string pattern = 2; +} + +message SearchResp { + repeated ListMailHeader found = 1; +} + +message FoldersReq { +} + +message FoldersResp { + repeated string folders = 1; +} + +message MoveReq { + string mid = 1; + string from_f = 2; + string to_f = 3; +} + +message MoveResp { +} + +message RemoveReq { + string folder = 1; + string mid = 2; +} + +message RemoveResp { +} + +service MailService { + rpc List(ListReq) returns (ListResp); + rpc Stats(StatsReq) returns (StatsResp); + rpc Show(ShowReq) returns (ShowResp); + rpc Raw(RawReq) returns (RawResp); + rpc Search(SearchReq) returns (SearchResp); + rpc Folders(FoldersReq) returns (FoldersResp); + rpc Move(MoveReq) returns (MoveResp); + rpc Remove(RemoveReq) returns (RemoveResp); +} diff --git a/src/arguments.rs b/src/arguments.rs index bd0fdcb..c017744 100644 --- a/src/arguments.rs +++ b/src/arguments.rs @@ -1,105 +1,17 @@ use std::path::PathBuf; -use clap::{value_parser, Parser, Subcommand}; +use clap::{Parser, ValueEnum}; -use crate::error::Error; - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum SortKey { - Date, - Sender, - Subject, - Size, -} - -#[derive(PartialEq, Eq, Clone)] -pub enum SortOrder { - Ascending, - Descending, -} - -#[derive(PartialEq, Eq, Clone)] -pub struct SortInfo { - pub key: SortKey, - pub order: SortOrder, -} - -impl std::str::FromStr for SortInfo { - type Err = Error; - - fn from_str(mut value: &str) -> Result<Self, Self::Err> { - if value == "" { - return Ok(SortInfo { - key: SortKey::Date, - order: SortOrder::Ascending, - }); - } - let order = if value.starts_with('!') { - value = &value[1..]; - SortOrder::Descending - } else { - SortOrder::Ascending - }; - let key = match value.to_ascii_lowercase().as_str() { - "date" => SortKey::Date, - "sender" => SortKey::Sender, - "subject" => SortKey::Subject, - "size" => SortKey::Size, - v => return Err(Error::SortOrder(format!("invalid sort order {:}", v))), - }; - Ok(SortInfo { key, order }) - } -} - -impl std::fmt::Debug for SortInfo { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { - write!( - f, - "{}{:?}", - match self.order { - SortOrder::Descending => "!", - SortOrder::Ascending => "", - }, - self.key - ) - } -} - -#[derive(Subcommand)] +#[derive(Clone, ValueEnum)] pub enum Mode { - List { - subfolder: String, - start: usize, - end: usize, - #[arg(value_parser = value_parser!(SortInfo))] - sortby: SortInfo, - }, - Search { - pattern: String, - subfolder: String, - }, - Count { - subfolder: String, - }, - Read { - subfolder: String, - mid: String, - }, - Raw { - subfolder: String, - mid: String, - mime_path: String, - }, + List, + Search, + Count, + Read, + Raw, Folders, - Move { - mid: String, - from: String, - to: String, - }, - Remove { - subfolder: String, - mid: String, - }, + Move, + Remove, } #[derive(Parser)] @@ -108,22 +20,5 @@ pub struct Arguments { pub maildir_path: PathBuf, pub sys_user: String, pub mail_user: String, - #[command(subcommand)] pub mode: Mode, } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn sort_info() { - assert_eq!( - "!date".parse::<SortInfo>().unwrap(), - SortInfo { - key: SortKey::Date, - order: SortOrder::Descending - } - ); - } -} @@ -1,68 +1,22 @@ -use std::io::ErrorKind as IOErrKind; use std::path::PathBuf; use maildir::Maildir; -use serde::Serialize as _; -use serde::Serializer as _; mod count; mod folders; -mod list; +mod move_mail; mod raw; +mod read; +mod list; +mod remove; -use crate::error::Result; -use crate::rfc822::{MIMEHeader, Mail, TopMailHeader}; - -pub use count::{count, CountInfo}; +pub use count::count; pub use folders::folders; -pub use list::list; +pub use move_mail::move_mail; pub use raw::raw; - -pub enum Return { - Read(Mail), - Raw(MIMEHeader, Vec<u8>), - List(Vec<TopMailHeader>), - Folders(Vec<String>), - Count(CountInfo), - Search(Vec<Mail>), - Move, - Remove, -} - -pub fn serialize_to<W>(res: Result<Return>, mut write: W) -> std::io::Result<()> -where - W: std::io::Write + Copy, -{ - let ser = &mut serde_json::Serializer::new(write); - - match res { - Err(e) => { - e.serialize(ser)?; - std::process::exit(3) - } - Ok(r) => { - match r { - Return::Folders(fs) => fs.serialize(ser), - Return::Count(ci) => ci.serialize(ser), - Return::List(tmhs) => tmhs.serialize(ser), - Return::Search(ms) => ms.serialize(ser), - Return::Read(m) => m.serialize(ser), - Return::Raw(mh, b) => { - let r = match mh.serialize(ser) { - Ok(x) => x, - Err(e) => return Err(e.into()), - }; - write.write_all(b"\n")?; - write.write_all(&b)?; - Ok(r) - } - Return::Move => ser.serialize_unit(), - Return::Remove => ser.serialize_unit(), - }?; - Ok(()) - } - } -} +pub use read::read; +pub use list::list; +pub use remove::remove; pub fn open_submaildir(mut path: PathBuf, sub: &str) -> Maildir { if sub != "" { @@ -70,28 +24,3 @@ pub fn open_submaildir(mut path: PathBuf, sub: &str) -> Maildir { } Maildir::from(path) } - -pub fn read(md: &Maildir, mid: &str) -> Result<Mail> { - md.add_flags(mid, "S")?; - - let mut mail = md.find(mid).ok_or_else(|| { - std::io::Error::new(IOErrKind::NotFound, format!("mail {} not found", mid)) - })?; - - Ok(mail.parsed()?.try_into()?) -} - -pub fn move_mail(p: PathBuf, mid: &str, from_f: &str, to_f: &str) -> Result<()> { - let from = open_submaildir(p.clone(), from_f); - let to = open_submaildir(p, to_f); - from.move_to(mid, &to).map_err(|e| e.into()) -} - -pub fn remove_mail(p: PathBuf, sub: &str, mid: &str) -> Result<()> { - let md = open_submaildir(p, sub); - md.add_flags(mid, "T").map_err(|e| e.into()) -} - -pub fn search(_md: &Maildir, _pattern: &str) -> Result<Vec<Mail>> { - todo!() -} diff --git a/src/cmd/count.rs b/src/cmd/count.rs index 0a6e883..5de542b 100644 --- a/src/cmd/count.rs +++ b/src/cmd/count.rs @@ -1,27 +1,27 @@ -use maildir::Maildir; -use serde::Serialize; +use std::path::PathBuf; +use protobuf::Message; + +use crate::cmd::open_submaildir; use crate::error::Result; +use crate::pb3::jwebmail::{StatsReq, StatsResp}; -#[derive(Serialize)] -pub struct CountInfo { - total_mails: u32, - byte_size: u64, - unread_mails: u32, -} +pub fn count(path: PathBuf, req: &[u8]) -> Result<Vec<u8>> { + let r = StatsReq::parse_from_bytes(req)?; + + let md = open_submaildir(path, &r.folder); -pub fn count(md: &Maildir) -> Result<CountInfo> { - Ok(CountInfo { - total_mails: md.count_cur() as u32, - unread_mails: md - .list_cur() - .filter(|x| x.as_ref().map_or(false, |z| !z.is_seen())) - .count() as u32, - byte_size: md - .path() - .join("cur") - .read_dir()? - .map(|x| x.map_or(0, |z| z.metadata().map_or(0, |y| y.len()))) - .sum(), - }) + let mut resp = StatsResp::new(); + resp.mail_count = md.count_cur() as u32; + resp.unread_count = md + .list_cur() + .filter(|x| x.as_ref().map_or(false, |z| !z.is_seen())) + .count() as u32; + resp.byte_size = md + .path() + .join("cur") + .read_dir()? + .map(|x| x.map_or(0, |z| z.metadata().map_or(0, |y| y.len()))) + .sum(); + resp.write_to_bytes().map_err(|e| e.into()) } diff --git a/src/cmd/folders.rs b/src/cmd/folders.rs index 0133528..b6f7209 100644 --- a/src/cmd/folders.rs +++ b/src/cmd/folders.rs @@ -1,11 +1,12 @@ use std::collections::BTreeSet; use std::ffi::{OsStr, OsString}; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::sync::OnceLock; -use maildir::Maildir; +use protobuf::Message as _; use crate::error::Result; +use crate::pb3::jwebmail::{FoldersReq, FoldersResp}; static REQUIRED_MAILDIR_DIRS: OnceLock<BTreeSet<OsString>> = OnceLock::new(); @@ -36,15 +37,17 @@ fn is_mailsubdir(p: &Path) -> bool { .unwrap_or_default() } -pub fn folders(md: &Maildir) -> Result<Vec<String>> { - let root_path = md.path(); +pub fn folders(path: PathBuf, req: &[u8]) -> Result<Vec<u8>> { + let _ = FoldersReq::parse_from_bytes(req)?; - let subdirs = root_path + let subdirs = path .read_dir()? .filter_map(|d| d.ok()) .filter(|d| is_mailsubdir(&d.path())) .filter_map(|d| Some(d.path().file_name()?.to_string_lossy()[1..].to_owned())) .collect(); - Ok(subdirs) + let mut res = FoldersResp::new(); + res.folders = subdirs; + res.write_to_bytes().map_err(|e| e.into()) } diff --git a/src/cmd/list.rs b/src/cmd/list.rs index b77a311..65f128f 100644 --- a/src/cmd/list.rs +++ b/src/cmd/list.rs @@ -1,19 +1,21 @@ use std::cmp::Reverse; +use std::path::PathBuf; use log::warn; -use maildir::Maildir; +use protobuf::Message as _; -use crate::arguments::{SortInfo, SortKey, SortOrder}; +use crate::cmd::open_submaildir; use crate::error::Result; -use crate::rfc822::{MailHeader, TopMailHeader}; +use crate::pb3::jwebmail::{ListMailHeader, ListReq, ListResp, MailHeader}; +use crate::rfc822::me_to_lmh; fn from_or_sender<'a>(mh: &'a MailHeader) -> &'a str { - if mh.from.len() == 0 { + if mh.written_from.len() == 0 { warn!("mail without from"); panic!() } - if mh.from.len() == 1 { - &mh.from[0].address + if mh.written_from.len() == 1 { + &mh.written_from[0].address } else { &mh.sender.as_ref().unwrap().address } @@ -32,72 +34,79 @@ fn mid_to_rec_time(mid: &str) -> f64 { fn sort_by_and_take( mut entries: Vec<maildir::MailEntry>, - sortby: &SortInfo, + sortby: &str, s: usize, e: usize, -) -> Vec<TopMailHeader> { - match sortby.key { - SortKey::Date => { - match sortby.order { - SortOrder::Ascending => entries.sort_by(|a, b| { - mid_to_rec_time(a.id()) - .partial_cmp(&mid_to_rec_time(b.id())) - .unwrap() - }), - SortOrder::Descending => entries.sort_by(|b, a| { - mid_to_rec_time(a.id()) - .partial_cmp(&mid_to_rec_time(b.id())) - .unwrap() - }), - } +) -> Vec<ListMailHeader> { + match sortby { + "date" => { + entries.sort_by(|a, b| { + mid_to_rec_time(a.id()) + .partial_cmp(&mid_to_rec_time(b.id())) + .unwrap() + }); entries .drain(s..e) - .filter_map(|me| me.try_into().map_err(|e| warn!("{}", e)).ok()) + .filter_map(|me| me_to_lmh(me).map_err(|e| warn!("{}", e)).ok()) .collect() } - SortKey::Size => { - match sortby.order { - SortOrder::Ascending => { - entries.sort_by_cached_key(|a| a.path().metadata().map_or(0, |m| m.len())) - } - SortOrder::Descending => entries - .sort_by_cached_key(|a| Reverse(a.path().metadata().map_or(0, |m| m.len()))), - } + "!date" => { + entries.sort_by(|b, a| { + mid_to_rec_time(a.id()) + .partial_cmp(&mid_to_rec_time(b.id())) + .unwrap() + }); + entries + .drain(s..e) + .filter_map(|me| me_to_lmh(me).map_err(|e| warn!("{}", e)).ok()) + .collect() + } + "size" => { + entries.sort_by_cached_key(|a| a.path().metadata().map_or(0, |m| m.len())); entries .drain(s..e) - .filter_map(|me| me.try_into().map_err(|e| warn!("{}", e)).ok()) + .filter_map(|me| me_to_lmh(me).map_err(|e| warn!("{}", e)).ok()) .collect() } - SortKey::Subject => { - let mut x: Vec<TopMailHeader> = entries + "!size" => { + entries.sort_by_cached_key(|a| Reverse(a.path().metadata().map_or(0, |m| m.len()))); + entries + .drain(s..e) + .filter_map(|me| me_to_lmh(me).map_err(|e| warn!("{}", e)).ok()) + .collect() + } + "subject" | "!subject" => { + let mut x: Vec<ListMailHeader> = entries .drain(..) - .filter_map(|me| me.try_into().map_err(|e| warn!("{}", e)).ok()) + .filter_map(|me| me_to_lmh(me).map_err(|e| warn!("{}", e)).ok()) .collect(); - match sortby.order { - SortOrder::Ascending => x.sort_by(|a, b| a.head.subject.cmp(&b.head.subject)), - SortOrder::Descending => x.sort_by(|b, a| a.head.subject.cmp(&b.head.subject)), + if sortby.bytes().nth(0) == Some(b'!') { + x.sort_by(|a, b| a.header.subject.cmp(&b.header.subject)) + } else { + x.sort_by(|b, a| a.header.subject.cmp(&b.header.subject)) } x.drain(s..e).collect() } - SortKey::Sender => { - let mut x: Vec<TopMailHeader> = entries + "sender" | "!sender" => { + let mut x: Vec<ListMailHeader> = entries .drain(..) - .filter_map(|me| me.try_into().map_err(|e| warn!("{}", e)).ok()) + .filter_map(|me| me_to_lmh(me).map_err(|e| warn!("{}", e)).ok()) .collect(); - match sortby.order { - SortOrder::Ascending => { - x.sort_by(|a, b| from_or_sender(&a.head).cmp(from_or_sender(&b.head))) - } - SortOrder::Descending => { - x.sort_by(|b, a| from_or_sender(&a.head).cmp(from_or_sender(&b.head))) - } + if sortby.bytes().nth(0) != Some(b'!') { + x.sort_by(|a, b| from_or_sender(&a.header).cmp(from_or_sender(&b.header))) + } else { + x.sort_by(|b, a| from_or_sender(&a.header).cmp(from_or_sender(&b.header))) } x.drain(s..e).collect() } + _ => todo!(), } } -pub fn list(md: &Maildir, i: usize, j: usize, sortby: &SortInfo) -> Result<Vec<TopMailHeader>> { +pub fn list(path: PathBuf, req: &[u8]) -> Result<Vec<u8>> { + let r = ListReq::parse_from_bytes(req)?; + let md = open_submaildir(path, &r.folder); + for r in md.list_new() { match r { Err(e) => warn!("{}", e), @@ -110,7 +119,10 @@ pub fn list(md: &Maildir, i: usize, j: usize, sortby: &SortInfo) -> Result<Vec<T } let a: Vec<_> = md.list_cur().filter_map(std::result::Result::ok).collect(); - let start = std::cmp::min(a.len(), i); - let end = std::cmp::min(a.len(), j); - Ok(sort_by_and_take(a, sortby, start, end)) + let start = std::cmp::min(a.len(), r.start as usize); + let end = std::cmp::min(a.len(), r.end as usize); + + let mut resp = ListResp::new(); + resp.mail_heads = sort_by_and_take(a, &r.sort, start, end); + resp.write_to_bytes().map_err(|e| e.into()) } diff --git a/src/cmd/move_mail.rs b/src/cmd/move_mail.rs new file mode 100644 index 0000000..146e906 --- /dev/null +++ b/src/cmd/move_mail.rs @@ -0,0 +1,18 @@ +use std::path::PathBuf; + +use protobuf::Message as _; + +use crate::cmd::open_submaildir; +use crate::error::Result; +use crate::pb3::jwebmail::{MoveReq, MoveResp}; + +pub fn move_mail(p: PathBuf, req: &[u8]) -> Result<Vec<u8>> { + let r = MoveReq::parse_from_bytes(req)?; + + let from = open_submaildir(p.clone(), &r.from_f); + let to = open_submaildir(p, &r.to_f); + from.move_to(&r.mid, &to)?; + + let resp = MoveResp::new(); + resp.write_to_bytes().map_err(|e| e.into()) +} diff --git a/src/cmd/raw.rs b/src/cmd/raw.rs index 70e2632..76c875f 100644 --- a/src/cmd/raw.rs +++ b/src/cmd/raw.rs @@ -1,89 +1,106 @@ use std::fs::read; use std::io::ErrorKind as IOErrKind; +use std::path::PathBuf; -use maildir::Maildir; +use protobuf::Message as _; +use crate::cmd::open_submaildir; use crate::error::{Error, Result}; -use crate::rfc822::{parse_mail_content, MIMEHeader}; +use crate::pb3::jwebmail::mimeheader::ContentDisposition::*; +use crate::pb3::jwebmail::{MIMEHeader, RawReq, RawResp}; +use crate::rfc822::parse_mail_content; -pub fn raw(md: &Maildir, mid: &str, mime_path: &str) -> Result<(MIMEHeader, Vec<u8>)> { - let mut mail = md.find(mid).ok_or_else(|| { - std::io::Error::new(IOErrKind::NotFound, format!("mail {} not found", mid)) +pub fn raw(md_path: PathBuf, req: &[u8]) -> Result<Vec<u8>> { + let r = RawReq::parse_from_bytes(req)?; + + let md = open_submaildir(md_path, &r.folder); + + let mut mail = md.find(&r.mid).ok_or_else(|| { + std::io::Error::new(IOErrKind::NotFound, format!("mail {} not found", &r.mid)) })?; - if mime_path.is_empty() { - let mh = MIMEHeader { - maintype: "message".to_owned(), - subtype: "rfc822".to_owned(), - filename: mail.id().to_owned(), - content_disposition: "".to_owned(), - }; + match r.path { + None => { + let mut mh = MIMEHeader::new(); - return Ok((mh, read(mail.path())?)); - } + mh.maintype = "message".to_owned(); + mh.subtype = "rfc822".to_owned(); + mh.file_name = Some(mail.id().to_owned()); + mh.contentdispo = CONTENT_DISPOSITION_NONE.into(); - let path = mime_path - .split('.') - .map(|x| { - x.parse() - .map_err(|pe: std::num::ParseIntError| Error::PathError { - msg: pe.to_string(), - path: mime_path.to_owned(), + let mut resp = RawResp::new(); + resp.header = Some(mh).into(); + resp.body = read(mail.path())?; + resp.write_to_bytes().map_err(|e| e.into()) + } + Some(mime_path) => { + let path = mime_path + .split('.') + .map(|x| { + x.parse() + .map_err(|pe: std::num::ParseIntError| Error::PathError { + msg: pe.to_string(), + path: mime_path.to_owned(), + }) }) - }) - .collect::<Result<Vec<_>>>()?; - let mut m = mail.parsed()?; + .collect::<Result<Vec<_>>>()?; + let mut m = mail.parsed()?; - if path[0] != 0 { - return Err(Error::PathError { - msg: "Message must be accessed by a 0".to_owned(), - path: mime_path.to_owned(), - }); - } - - for i in &path[1..] { - match &m.ctype.mimetype { - x if x.starts_with("message/") => { - if *i != 0 { - return Err(Error::PathError { - msg: "Message must be accessed by a 0".to_owned(), - path: mime_path.to_owned(), - }); - } - let s: &'static _ = m.get_body_raw()?.leak(); - m = mailparse::parse_mail(s)?; + if path[0] != 0 { + return Err(Error::PathError { + msg: "Message must be accessed by a 0".to_owned(), + path: mime_path.to_owned(), + }); } - x if x.starts_with("multipart/") => { - if *i >= m.subparts.len() { - return Err(Error::PathError { - msg: "Out of bounds access".to_owned(), - path: mime_path.to_owned(), - }); + + for i in &path[1..] { + match &m.ctype.mimetype { + x if x.starts_with("message/") => { + if *i != 0 { + return Err(Error::PathError { + msg: "Message must be accessed by a 0".to_owned(), + path: mime_path.to_owned(), + }); + } + let s: &'static _ = m.get_body_raw()?.leak(); + m = mailparse::parse_mail(s)?; + } + x if x.starts_with("multipart/") => { + if *i >= m.subparts.len() { + return Err(Error::PathError { + msg: "Out of bounds access".to_owned(), + path: mime_path.to_owned(), + }); + } + m = m.subparts.swap_remove(*i); + } + _ => { + return Err(Error::PathError { + msg: "Unable to descent into leaf component".to_owned(), + path: mime_path.to_owned(), + }) + } } - m = m.subparts.swap_remove(*i); } - _ => { + + if m.ctype.mimetype.starts_with("multipart/") { return Err(Error::PathError { - msg: "Unable to descent into leaf component".to_owned(), + msg: "Can not show multipart component".to_owned(), path: mime_path.to_owned(), - }) + }); } - } - } - if m.ctype.mimetype.starts_with("multipart/") { - return Err(Error::PathError { - msg: "Can not show multipart component".to_owned(), - path: mime_path.to_owned(), - }); - } - - let mime_part = parse_mail_content(&m)?; - let content = if m.ctype.mimetype.starts_with("text/") { - m.get_body()?.into_bytes() - } else { - m.get_body_raw()? - }; + let mime_part = parse_mail_content(&m)?; + let content = if m.ctype.mimetype.starts_with("text/") { + m.get_body()?.into_bytes() + } else { + m.get_body_raw()? + }; - Ok((mime_part, content)) + let mut resp = RawResp::new(); + resp.header = Some(mime_part).into(); + resp.body = content; + resp.write_to_bytes().map_err(|e| e.into()) + } + } } diff --git a/src/cmd/read.rs b/src/cmd/read.rs new file mode 100644 index 0000000..797f4d6 --- /dev/null +++ b/src/cmd/read.rs @@ -0,0 +1,24 @@ +use std::io::ErrorKind as IOErrKind; +use std::path::PathBuf; + +use protobuf::Message as _; + +use crate::cmd::open_submaildir; +use crate::error::Result; +use crate::pb3::jwebmail::{ShowReq, ShowResp}; +use crate::rfc822::parsed_mail_to_mail; + +pub fn read(path: PathBuf, req: &[u8]) -> Result<Vec<u8>> { + let r = ShowReq::parse_from_bytes(req)?; + let md = open_submaildir(path, &r.folder); + + md.add_flags(&r.mid, "S")?; + + let mut mail = md.find(&r.mid).ok_or_else(|| { + std::io::Error::new(IOErrKind::NotFound, format!("mail {} not found", &r.mid)) + })?; + + let mut resp = ShowResp::new(); + resp.mail = Some(parsed_mail_to_mail(mail.parsed()?)?).into(); + resp.write_to_bytes().map_err(|e| e.into()) +} diff --git a/src/cmd/remove.rs b/src/cmd/remove.rs new file mode 100644 index 0000000..8d26e68 --- /dev/null +++ b/src/cmd/remove.rs @@ -0,0 +1,17 @@ +use std::path::PathBuf; + +use protobuf::Message as _; + +use crate::cmd::open_submaildir; +use crate::error::Result; +use crate::pb3::jwebmail::{RemoveReq, RemoveResp}; + +pub fn remove(p: PathBuf, req: &[u8]) -> Result<Vec<u8>> { + let r = RemoveReq::parse_from_bytes(req)?; + + let md = open_submaildir(p, &r.folder); + md.add_flags(&r.mid, "T")?; + + let resp = RemoveResp::new(); + resp.write_to_bytes().map_err(|e| e.into()) +} diff --git a/src/error.rs b/src/error.rs index fc0a21a..0c0167f 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,9 +1,6 @@ -use std::borrow::Cow; - use maildir::MailEntryError; use mailparse::MailParseError; -use serde::ser::SerializeStruct as _; -use serde_json::Error as JSONError; +use protobuf::Error as PBError; pub type Result<T> = std::result::Result<T, Error>; @@ -13,7 +10,7 @@ pub enum Error { MailEntryError(MailEntryError), SortOrder(String), Setuid(String), - JSONError(JSONError), + Protobuf(PBError), PathError { msg: String, path: String }, } @@ -25,25 +22,6 @@ impl std::fmt::Display for Error { impl std::error::Error for Error {} -impl serde::Serialize for Error { - fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error> - where - S: serde::Serializer, - { - let mut state = serializer.serialize_struct("Error", 1)?; - let err_str: Cow<str> = match self { - Error::IoError(e) => Cow::Owned(e.to_string()), - Error::MailEntryError(e) => Cow::Owned(e.to_string()), - Error::SortOrder(s) => Cow::Borrowed(s), - Error::Setuid(s) => Cow::Borrowed(s), - Error::JSONError(e) => Cow::Owned(e.to_string()), - Error::PathError { msg, path } => Cow::Owned(format!("{} {:?}", msg, path)), - }; - state.serialize_field("error", &err_str)?; - state.end() - } -} - impl From<std::io::Error> for Error { fn from(io_err: std::io::Error) -> Self { Error::IoError(io_err) @@ -62,8 +40,8 @@ impl From<MailParseError> for Error { } } -impl From<JSONError> for Error { - fn from(j_err: JSONError) -> Self { - Error::JSONError(j_err) +impl From<PBError> for Error { + fn from(pb_err: PBError) -> Self { + Error::Protobuf(pb_err) } } diff --git a/src/main.rs b/src/main.rs index 0b216dc..942961b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,19 +1,15 @@ use std::ffi::{CStr, CString}; -use std::io::stdout; +use std::io::{stdin, stdout, Read, Write}; use clap::Parser as _; -use maildir::Maildir; mod arguments; mod cmd; mod error; +mod pb3; mod rfc822; use arguments::{Arguments, Mode}; -use cmd::{ - count, folders, list, move_mail, open_submaildir, raw, read, remove_mail, search, serialize_to, - Return, -}; use error::{Error, Result}; fn switch_to_user(sys_user: &str) -> Result<()> { @@ -44,7 +40,7 @@ fn switch_to_user(sys_user: &str) -> Result<()> { Ok(()) } -fn main() -> std::io::Result<()> { +fn main() -> Result<()> { simplelog::TermLogger::init( simplelog::LevelFilter::Info, simplelog::Config::default(), @@ -55,39 +51,26 @@ fn main() -> std::io::Result<()> { let args = Arguments::parse(); - std::env::remove_var("PATH"); - if let Err(e) = switch_to_user(&args.sys_user) { - serialize_to(Err(e), &stdout())? - } + switch_to_user(&args.sys_user)?; let path = args.maildir_path.join(args.mail_user); + stdout().write(b"OPEN\n")?; + stdout().flush()?; + let mut req = Vec::with_capacity(2048); + stdin().read_to_end(&mut req)?; + let res = match args.mode { - Mode::Read { subfolder, mid } => { - read(&open_submaildir(path, &subfolder), &mid).map(Return::Read) - } - Mode::Raw { - subfolder, - mid, - mime_path, - } => raw(&open_submaildir(path, &subfolder), &mid, &mime_path) - .map(|(h, t)| Return::Raw(h, t)), - Mode::List { - subfolder, - start, - end, - ref sortby, - } => list(&open_submaildir(path, &subfolder), start, end, sortby).map(Return::List), - Mode::Folders => folders(&Maildir::from(path)).map(Return::Folders), - Mode::Count { subfolder } => count(&open_submaildir(path, &subfolder)).map(Return::Count), - Mode::Search { pattern, subfolder } => { - search(&open_submaildir(path, &subfolder), &pattern).map(Return::Search) - } - Mode::Move { mid, from, to } => move_mail(path, &mid, &from, &to).map(|()| Return::Move), - Mode::Remove { subfolder, mid } => { - remove_mail(path, &subfolder, &mid).map(|()| Return::Remove) - } - }; + Mode::Read => cmd::read(path, &req), + Mode::Raw => cmd::raw(path, &req), + Mode::List => cmd::list(path, &req), + Mode::Folders => cmd::folders(path, &req), + Mode::Count => cmd::count(path, &req), + //Mode::Search => cmd::search(&path, &req), + Mode::Move => cmd::move_mail(path, &req), + Mode::Remove => cmd::remove(path, &req), + _ => todo!(), + }?; - serialize_to(res, &stdout()) + stdout().write(&res).map(|_| ()).map_err(|e| e.into()) } diff --git a/src/pb3/jwebmail.rs b/src/pb3/jwebmail.rs new file mode 100644 index 0000000..c94a0e1 --- /dev/null +++ b/src/pb3/jwebmail.rs @@ -0,0 +1,3966 @@ +// This file is generated by rust-protobuf 3.4.0. Do not edit +// .proto file is parsed by protoc 25.3 +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_results)] +#![allow(unused_mut)] + +//! Generated file from `jwebmail.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_3_4_0; + +// @@protoc_insertion_point(message:jwebmail.MIMEHeader) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct MIMEHeader { + // message fields + // @@protoc_insertion_point(field:jwebmail.MIMEHeader.maintype) + pub maintype: ::std::string::String, + // @@protoc_insertion_point(field:jwebmail.MIMEHeader.subtype) + pub subtype: ::std::string::String, + // @@protoc_insertion_point(field:jwebmail.MIMEHeader.contentdispo) + pub contentdispo: ::protobuf::EnumOrUnknown<mimeheader::ContentDisposition>, + // @@protoc_insertion_point(field:jwebmail.MIMEHeader.file_name) + pub file_name: ::std::option::Option<::std::string::String>, + // special fields + // @@protoc_insertion_point(special_field:jwebmail.MIMEHeader.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a MIMEHeader { + fn default() -> &'a MIMEHeader { + <MIMEHeader as ::protobuf::Message>::default_instance() + } +} + +impl MIMEHeader { + pub fn new() -> MIMEHeader { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(4); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "maintype", + |m: &MIMEHeader| { &m.maintype }, + |m: &mut MIMEHeader| { &mut m.maintype }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "subtype", + |m: &MIMEHeader| { &m.subtype }, + |m: &mut MIMEHeader| { &mut m.subtype }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "contentdispo", + |m: &MIMEHeader| { &m.contentdispo }, + |m: &mut MIMEHeader| { &mut m.contentdispo }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "file_name", + |m: &MIMEHeader| { &m.file_name }, + |m: &mut MIMEHeader| { &mut m.file_name }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<MIMEHeader>( + "MIMEHeader", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for MIMEHeader { + const NAME: &'static str = "MIMEHeader"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.maintype = is.read_string()?; + }, + 18 => { + self.subtype = is.read_string()?; + }, + 24 => { + self.contentdispo = is.read_enum_or_unknown()?; + }, + 34 => { + self.file_name = ::std::option::Option::Some(is.read_string()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if !self.maintype.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.maintype); + } + if !self.subtype.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.subtype); + } + if self.contentdispo != ::protobuf::EnumOrUnknown::new(mimeheader::ContentDisposition::CONTENT_DISPOSITION_NONE) { + my_size += ::protobuf::rt::int32_size(3, self.contentdispo.value()); + } + if let Some(v) = self.file_name.as_ref() { + my_size += ::protobuf::rt::string_size(4, &v); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if !self.maintype.is_empty() { + os.write_string(1, &self.maintype)?; + } + if !self.subtype.is_empty() { + os.write_string(2, &self.subtype)?; + } + if self.contentdispo != ::protobuf::EnumOrUnknown::new(mimeheader::ContentDisposition::CONTENT_DISPOSITION_NONE) { + os.write_enum(3, ::protobuf::EnumOrUnknown::value(&self.contentdispo))?; + } + if let Some(v) = self.file_name.as_ref() { + os.write_string(4, v)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> MIMEHeader { + MIMEHeader::new() + } + + fn clear(&mut self) { + self.maintype.clear(); + self.subtype.clear(); + self.contentdispo = ::protobuf::EnumOrUnknown::new(mimeheader::ContentDisposition::CONTENT_DISPOSITION_NONE); + self.file_name = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static MIMEHeader { + static instance: MIMEHeader = MIMEHeader { + maintype: ::std::string::String::new(), + subtype: ::std::string::String::new(), + contentdispo: ::protobuf::EnumOrUnknown::from_i32(0), + file_name: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for MIMEHeader { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("MIMEHeader").unwrap()).clone() + } +} + +impl ::std::fmt::Display for MIMEHeader { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MIMEHeader { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; +} + +/// Nested message and enums of message `MIMEHeader` +pub mod mimeheader { + #[derive(Clone,Copy,PartialEq,Eq,Debug,Hash)] + // @@protoc_insertion_point(enum:jwebmail.MIMEHeader.ContentDisposition) + pub enum ContentDisposition { + // @@protoc_insertion_point(enum_value:jwebmail.MIMEHeader.ContentDisposition.CONTENT_DISPOSITION_NONE) + CONTENT_DISPOSITION_NONE = 0, + // @@protoc_insertion_point(enum_value:jwebmail.MIMEHeader.ContentDisposition.CONTENT_DISPOSITION_INLINE) + CONTENT_DISPOSITION_INLINE = 1, + // @@protoc_insertion_point(enum_value:jwebmail.MIMEHeader.ContentDisposition.CONTENT_DISPOSITION_ATTACHMENT) + CONTENT_DISPOSITION_ATTACHMENT = 2, + } + + impl ::protobuf::Enum for ContentDisposition { + const NAME: &'static str = "ContentDisposition"; + + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option<ContentDisposition> { + match value { + 0 => ::std::option::Option::Some(ContentDisposition::CONTENT_DISPOSITION_NONE), + 1 => ::std::option::Option::Some(ContentDisposition::CONTENT_DISPOSITION_INLINE), + 2 => ::std::option::Option::Some(ContentDisposition::CONTENT_DISPOSITION_ATTACHMENT), + _ => ::std::option::Option::None + } + } + + fn from_str(str: &str) -> ::std::option::Option<ContentDisposition> { + match str { + "CONTENT_DISPOSITION_NONE" => ::std::option::Option::Some(ContentDisposition::CONTENT_DISPOSITION_NONE), + "CONTENT_DISPOSITION_INLINE" => ::std::option::Option::Some(ContentDisposition::CONTENT_DISPOSITION_INLINE), + "CONTENT_DISPOSITION_ATTACHMENT" => ::std::option::Option::Some(ContentDisposition::CONTENT_DISPOSITION_ATTACHMENT), + _ => ::std::option::Option::None + } + } + + const VALUES: &'static [ContentDisposition] = &[ + ContentDisposition::CONTENT_DISPOSITION_NONE, + ContentDisposition::CONTENT_DISPOSITION_INLINE, + ContentDisposition::CONTENT_DISPOSITION_ATTACHMENT, + ]; + } + + impl ::protobuf::EnumFull for ContentDisposition { + fn enum_descriptor() -> ::protobuf::reflect::EnumDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| super::file_descriptor().enum_by_package_relative_name("MIMEHeader.ContentDisposition").unwrap()).clone() + } + + fn descriptor(&self) -> ::protobuf::reflect::EnumValueDescriptor { + let index = *self as usize; + Self::enum_descriptor().value_by_index(index) + } + } + + impl ::std::default::Default for ContentDisposition { + fn default() -> Self { + ContentDisposition::CONTENT_DISPOSITION_NONE + } + } + + impl ContentDisposition { + pub(in super) fn generated_enum_descriptor_data() -> ::protobuf::reflect::GeneratedEnumDescriptorData { + ::protobuf::reflect::GeneratedEnumDescriptorData::new::<ContentDisposition>("MIMEHeader.ContentDisposition") + } + } +} + +// @@protoc_insertion_point(message:jwebmail.MailHeader) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct MailHeader { + // message fields + // @@protoc_insertion_point(field:jwebmail.MailHeader.send_date) + pub send_date: ::std::string::String, + // @@protoc_insertion_point(field:jwebmail.MailHeader.written_from) + pub written_from: ::std::vec::Vec<mail_header::MailAddr>, + // @@protoc_insertion_point(field:jwebmail.MailHeader.sender) + pub sender: ::protobuf::MessageField<mail_header::MailAddr>, + // @@protoc_insertion_point(field:jwebmail.MailHeader.reply_to) + pub reply_to: ::std::vec::Vec<mail_header::MailAddr>, + // @@protoc_insertion_point(field:jwebmail.MailHeader.send_to) + pub send_to: ::std::vec::Vec<mail_header::MailAddr>, + // @@protoc_insertion_point(field:jwebmail.MailHeader.cc) + pub cc: ::std::vec::Vec<mail_header::MailAddr>, + // @@protoc_insertion_point(field:jwebmail.MailHeader.bcc) + pub bcc: ::std::vec::Vec<mail_header::MailAddr>, + // @@protoc_insertion_point(field:jwebmail.MailHeader.subject) + pub subject: ::std::string::String, + // @@protoc_insertion_point(field:jwebmail.MailHeader.comments) + pub comments: ::std::vec::Vec<::std::string::String>, + // @@protoc_insertion_point(field:jwebmail.MailHeader.keywords) + pub keywords: ::std::vec::Vec<::std::string::String>, + // @@protoc_insertion_point(field:jwebmail.MailHeader.mime) + pub mime: ::protobuf::MessageField<MIMEHeader>, + // special fields + // @@protoc_insertion_point(special_field:jwebmail.MailHeader.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a MailHeader { + fn default() -> &'a MailHeader { + <MailHeader as ::protobuf::Message>::default_instance() + } +} + +impl MailHeader { + pub fn new() -> MailHeader { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(11); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "send_date", + |m: &MailHeader| { &m.send_date }, + |m: &mut MailHeader| { &mut m.send_date }, + )); + fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( + "written_from", + |m: &MailHeader| { &m.written_from }, + |m: &mut MailHeader| { &mut m.written_from }, + )); + fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, mail_header::MailAddr>( + "sender", + |m: &MailHeader| { &m.sender }, + |m: &mut MailHeader| { &mut m.sender }, + )); + fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( + "reply_to", + |m: &MailHeader| { &m.reply_to }, + |m: &mut MailHeader| { &mut m.reply_to }, + )); + fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( + "send_to", + |m: &MailHeader| { &m.send_to }, + |m: &mut MailHeader| { &mut m.send_to }, + )); + fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( + "cc", + |m: &MailHeader| { &m.cc }, + |m: &mut MailHeader| { &mut m.cc }, + )); + fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( + "bcc", + |m: &MailHeader| { &m.bcc }, + |m: &mut MailHeader| { &mut m.bcc }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "subject", + |m: &MailHeader| { &m.subject }, + |m: &mut MailHeader| { &mut m.subject }, + )); + fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( + "comments", + |m: &MailHeader| { &m.comments }, + |m: &mut MailHeader| { &mut m.comments }, + )); + fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( + "keywords", + |m: &MailHeader| { &m.keywords }, + |m: &mut MailHeader| { &mut m.keywords }, + )); + fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, MIMEHeader>( + "mime", + |m: &MailHeader| { &m.mime }, + |m: &mut MailHeader| { &mut m.mime }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<MailHeader>( + "MailHeader", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for MailHeader { + const NAME: &'static str = "MailHeader"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.send_date = is.read_string()?; + }, + 18 => { + self.written_from.push(is.read_message()?); + }, + 26 => { + ::protobuf::rt::read_singular_message_into_field(is, &mut self.sender)?; + }, + 34 => { + self.reply_to.push(is.read_message()?); + }, + 42 => { + self.send_to.push(is.read_message()?); + }, + 50 => { + self.cc.push(is.read_message()?); + }, + 58 => { + self.bcc.push(is.read_message()?); + }, + 66 => { + self.subject = is.read_string()?; + }, + 74 => { + self.comments.push(is.read_string()?); + }, + 82 => { + self.keywords.push(is.read_string()?); + }, + 90 => { + ::protobuf::rt::read_singular_message_into_field(is, &mut self.mime)?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if !self.send_date.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.send_date); + } + for value in &self.written_from { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + }; + if let Some(v) = self.sender.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + } + for value in &self.reply_to { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + }; + for value in &self.send_to { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + }; + for value in &self.cc { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + }; + for value in &self.bcc { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + }; + if !self.subject.is_empty() { + my_size += ::protobuf::rt::string_size(8, &self.subject); + } + for value in &self.comments { + my_size += ::protobuf::rt::string_size(9, &value); + }; + for value in &self.keywords { + my_size += ::protobuf::rt::string_size(10, &value); + }; + if let Some(v) = self.mime.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if !self.send_date.is_empty() { + os.write_string(1, &self.send_date)?; + } + for v in &self.written_from { + ::protobuf::rt::write_message_field_with_cached_size(2, v, os)?; + }; + if let Some(v) = self.sender.as_ref() { + ::protobuf::rt::write_message_field_with_cached_size(3, v, os)?; + } + for v in &self.reply_to { + ::protobuf::rt::write_message_field_with_cached_size(4, v, os)?; + }; + for v in &self.send_to { + ::protobuf::rt::write_message_field_with_cached_size(5, v, os)?; + }; + for v in &self.cc { + ::protobuf::rt::write_message_field_with_cached_size(6, v, os)?; + }; + for v in &self.bcc { + ::protobuf::rt::write_message_field_with_cached_size(7, v, os)?; + }; + if !self.subject.is_empty() { + os.write_string(8, &self.subject)?; + } + for v in &self.comments { + os.write_string(9, &v)?; + }; + for v in &self.keywords { + os.write_string(10, &v)?; + }; + if let Some(v) = self.mime.as_ref() { + ::protobuf::rt::write_message_field_with_cached_size(11, v, os)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> MailHeader { + MailHeader::new() + } + + fn clear(&mut self) { + self.send_date.clear(); + self.written_from.clear(); + self.sender.clear(); + self.reply_to.clear(); + self.send_to.clear(); + self.cc.clear(); + self.bcc.clear(); + self.subject.clear(); + self.comments.clear(); + self.keywords.clear(); + self.mime.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static MailHeader { + static instance: MailHeader = MailHeader { + send_date: ::std::string::String::new(), + written_from: ::std::vec::Vec::new(), + sender: ::protobuf::MessageField::none(), + reply_to: ::std::vec::Vec::new(), + send_to: ::std::vec::Vec::new(), + cc: ::std::vec::Vec::new(), + bcc: ::std::vec::Vec::new(), + subject: ::std::string::String::new(), + comments: ::std::vec::Vec::new(), + keywords: ::std::vec::Vec::new(), + mime: ::protobuf::MessageField::none(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for MailHeader { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("MailHeader").unwrap()).clone() + } +} + +impl ::std::fmt::Display for MailHeader { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MailHeader { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; +} + +/// Nested message and enums of message `MailHeader` +pub mod mail_header { + // @@protoc_insertion_point(message:jwebmail.MailHeader.MailAddr) + #[derive(PartialEq,Clone,Default,Debug)] + pub struct MailAddr { + // message fields + // @@protoc_insertion_point(field:jwebmail.MailHeader.MailAddr.name) + pub name: ::std::option::Option<::std::string::String>, + // @@protoc_insertion_point(field:jwebmail.MailHeader.MailAddr.address) + pub address: ::std::string::String, + // special fields + // @@protoc_insertion_point(special_field:jwebmail.MailHeader.MailAddr.special_fields) + pub special_fields: ::protobuf::SpecialFields, + } + + impl<'a> ::std::default::Default for &'a MailAddr { + fn default() -> &'a MailAddr { + <MailAddr as ::protobuf::Message>::default_instance() + } + } + + impl MailAddr { + pub fn new() -> MailAddr { + ::std::default::Default::default() + } + + pub(in super) fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(2); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "name", + |m: &MailAddr| { &m.name }, + |m: &mut MailAddr| { &mut m.name }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "address", + |m: &MailAddr| { &m.address }, + |m: &mut MailAddr| { &mut m.address }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<MailAddr>( + "MailHeader.MailAddr", + fields, + oneofs, + ) + } + } + + impl ::protobuf::Message for MailAddr { + const NAME: &'static str = "MailAddr"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.name = ::std::option::Option::Some(is.read_string()?); + }, + 18 => { + self.address = is.read_string()?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.name.as_ref() { + my_size += ::protobuf::rt::string_size(1, &v); + } + if !self.address.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.address); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.name.as_ref() { + os.write_string(1, v)?; + } + if !self.address.is_empty() { + os.write_string(2, &self.address)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> MailAddr { + MailAddr::new() + } + + fn clear(&mut self) { + self.name = ::std::option::Option::None; + self.address.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static MailAddr { + static instance: MailAddr = MailAddr { + name: ::std::option::Option::None, + address: ::std::string::String::new(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } + } + + impl ::protobuf::MessageFull for MailAddr { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| super::file_descriptor().message_by_package_relative_name("MailHeader.MailAddr").unwrap()).clone() + } + } + + impl ::std::fmt::Display for MailAddr { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } + } + + impl ::protobuf::reflect::ProtobufValue for MailAddr { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; + } +} + +// @@protoc_insertion_point(message:jwebmail.ListMailHeader) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct ListMailHeader { + // message fields + // @@protoc_insertion_point(field:jwebmail.ListMailHeader.byte_size) + pub byte_size: u64, + // @@protoc_insertion_point(field:jwebmail.ListMailHeader.unread) + pub unread: bool, + // @@protoc_insertion_point(field:jwebmail.ListMailHeader.rec_date) + pub rec_date: ::std::string::String, + // @@protoc_insertion_point(field:jwebmail.ListMailHeader.mid) + pub mid: ::std::string::String, + // @@protoc_insertion_point(field:jwebmail.ListMailHeader.header) + pub header: ::protobuf::MessageField<MailHeader>, + // special fields + // @@protoc_insertion_point(special_field:jwebmail.ListMailHeader.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a ListMailHeader { + fn default() -> &'a ListMailHeader { + <ListMailHeader as ::protobuf::Message>::default_instance() + } +} + +impl ListMailHeader { + pub fn new() -> ListMailHeader { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(5); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "byte_size", + |m: &ListMailHeader| { &m.byte_size }, + |m: &mut ListMailHeader| { &mut m.byte_size }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "unread", + |m: &ListMailHeader| { &m.unread }, + |m: &mut ListMailHeader| { &mut m.unread }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "rec_date", + |m: &ListMailHeader| { &m.rec_date }, + |m: &mut ListMailHeader| { &mut m.rec_date }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "mid", + |m: &ListMailHeader| { &m.mid }, + |m: &mut ListMailHeader| { &mut m.mid }, + )); + fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, MailHeader>( + "header", + |m: &ListMailHeader| { &m.header }, + |m: &mut ListMailHeader| { &mut m.header }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<ListMailHeader>( + "ListMailHeader", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for ListMailHeader { + const NAME: &'static str = "ListMailHeader"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 8 => { + self.byte_size = is.read_uint64()?; + }, + 16 => { + self.unread = is.read_bool()?; + }, + 26 => { + self.rec_date = is.read_string()?; + }, + 34 => { + self.mid = is.read_string()?; + }, + 42 => { + ::protobuf::rt::read_singular_message_into_field(is, &mut self.header)?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if self.byte_size != 0 { + my_size += ::protobuf::rt::uint64_size(1, self.byte_size); + } + if self.unread != false { + my_size += 1 + 1; + } + if !self.rec_date.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.rec_date); + } + if !self.mid.is_empty() { + my_size += ::protobuf::rt::string_size(4, &self.mid); + } + if let Some(v) = self.header.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if self.byte_size != 0 { + os.write_uint64(1, self.byte_size)?; + } + if self.unread != false { + os.write_bool(2, self.unread)?; + } + if !self.rec_date.is_empty() { + os.write_string(3, &self.rec_date)?; + } + if !self.mid.is_empty() { + os.write_string(4, &self.mid)?; + } + if let Some(v) = self.header.as_ref() { + ::protobuf::rt::write_message_field_with_cached_size(5, v, os)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> ListMailHeader { + ListMailHeader::new() + } + + fn clear(&mut self) { + self.byte_size = 0; + self.unread = false; + self.rec_date.clear(); + self.mid.clear(); + self.header.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static ListMailHeader { + static instance: ListMailHeader = ListMailHeader { + byte_size: 0, + unread: false, + rec_date: ::std::string::String::new(), + mid: ::std::string::String::new(), + header: ::protobuf::MessageField::none(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for ListMailHeader { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("ListMailHeader").unwrap()).clone() + } +} + +impl ::std::fmt::Display for ListMailHeader { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for ListMailHeader { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; +} + +// @@protoc_insertion_point(message:jwebmail.MailBody) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct MailBody { + // message oneof groups + pub Body: ::std::option::Option<mail_body::Body>, + // special fields + // @@protoc_insertion_point(special_field:jwebmail.MailBody.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a MailBody { + fn default() -> &'a MailBody { + <MailBody as ::protobuf::Message>::default_instance() + } +} + +impl MailBody { + pub fn new() -> MailBody { + ::std::default::Default::default() + } + + // string discrete = 1; + + pub fn discrete(&self) -> &str { + match self.Body { + ::std::option::Option::Some(mail_body::Body::Discrete(ref v)) => v, + _ => "", + } + } + + pub fn clear_discrete(&mut self) { + self.Body = ::std::option::Option::None; + } + + pub fn has_discrete(&self) -> bool { + match self.Body { + ::std::option::Option::Some(mail_body::Body::Discrete(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_discrete(&mut self, v: ::std::string::String) { + self.Body = ::std::option::Option::Some(mail_body::Body::Discrete(v)) + } + + // Mutable pointer to the field. + pub fn mut_discrete(&mut self) -> &mut ::std::string::String { + if let ::std::option::Option::Some(mail_body::Body::Discrete(_)) = self.Body { + } else { + self.Body = ::std::option::Option::Some(mail_body::Body::Discrete(::std::string::String::new())); + } + match self.Body { + ::std::option::Option::Some(mail_body::Body::Discrete(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_discrete(&mut self) -> ::std::string::String { + if self.has_discrete() { + match self.Body.take() { + ::std::option::Option::Some(mail_body::Body::Discrete(v)) => v, + _ => panic!(), + } + } else { + ::std::string::String::new() + } + } + + // .jwebmail.MailBody.Multipart multipart = 2; + + pub fn multipart(&self) -> &mail_body::Multipart { + match self.Body { + ::std::option::Option::Some(mail_body::Body::Multipart(ref v)) => v, + _ => <mail_body::Multipart as ::protobuf::Message>::default_instance(), + } + } + + pub fn clear_multipart(&mut self) { + self.Body = ::std::option::Option::None; + } + + pub fn has_multipart(&self) -> bool { + match self.Body { + ::std::option::Option::Some(mail_body::Body::Multipart(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_multipart(&mut self, v: mail_body::Multipart) { + self.Body = ::std::option::Option::Some(mail_body::Body::Multipart(v)) + } + + // Mutable pointer to the field. + pub fn mut_multipart(&mut self) -> &mut mail_body::Multipart { + if let ::std::option::Option::Some(mail_body::Body::Multipart(_)) = self.Body { + } else { + self.Body = ::std::option::Option::Some(mail_body::Body::Multipart(mail_body::Multipart::new())); + } + match self.Body { + ::std::option::Option::Some(mail_body::Body::Multipart(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_multipart(&mut self) -> mail_body::Multipart { + if self.has_multipart() { + match self.Body.take() { + ::std::option::Option::Some(mail_body::Body::Multipart(v)) => v, + _ => panic!(), + } + } else { + mail_body::Multipart::new() + } + } + + // .jwebmail.Mail mail = 3; + + pub fn mail(&self) -> &Mail { + match self.Body { + ::std::option::Option::Some(mail_body::Body::Mail(ref v)) => v, + _ => <Mail as ::protobuf::Message>::default_instance(), + } + } + + pub fn clear_mail(&mut self) { + self.Body = ::std::option::Option::None; + } + + pub fn has_mail(&self) -> bool { + match self.Body { + ::std::option::Option::Some(mail_body::Body::Mail(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_mail(&mut self, v: Mail) { + self.Body = ::std::option::Option::Some(mail_body::Body::Mail(v)) + } + + // Mutable pointer to the field. + pub fn mut_mail(&mut self) -> &mut Mail { + if let ::std::option::Option::Some(mail_body::Body::Mail(_)) = self.Body { + } else { + self.Body = ::std::option::Option::Some(mail_body::Body::Mail(Mail::new())); + } + match self.Body { + ::std::option::Option::Some(mail_body::Body::Mail(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_mail(&mut self) -> Mail { + if self.has_mail() { + match self.Body.take() { + ::std::option::Option::Some(mail_body::Body::Mail(v)) => v, + _ => panic!(), + } + } else { + Mail::new() + } + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(3); + let mut oneofs = ::std::vec::Vec::with_capacity(1); + fields.push(::protobuf::reflect::rt::v2::make_oneof_deref_has_get_set_simpler_accessor::<_, _>( + "discrete", + MailBody::has_discrete, + MailBody::discrete, + MailBody::set_discrete, + )); + fields.push(::protobuf::reflect::rt::v2::make_oneof_message_has_get_mut_set_accessor::<_, mail_body::Multipart>( + "multipart", + MailBody::has_multipart, + MailBody::multipart, + MailBody::mut_multipart, + MailBody::set_multipart, + )); + fields.push(::protobuf::reflect::rt::v2::make_oneof_message_has_get_mut_set_accessor::<_, Mail>( + "mail", + MailBody::has_mail, + MailBody::mail, + MailBody::mut_mail, + MailBody::set_mail, + )); + oneofs.push(mail_body::Body::generated_oneof_descriptor_data()); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<MailBody>( + "MailBody", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for MailBody { + const NAME: &'static str = "MailBody"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.Body = ::std::option::Option::Some(mail_body::Body::Discrete(is.read_string()?)); + }, + 18 => { + self.Body = ::std::option::Option::Some(mail_body::Body::Multipart(is.read_message()?)); + }, + 26 => { + self.Body = ::std::option::Option::Some(mail_body::Body::Mail(is.read_message()?)); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let ::std::option::Option::Some(ref v) = self.Body { + match v { + &mail_body::Body::Discrete(ref v) => { + my_size += ::protobuf::rt::string_size(1, &v); + }, + &mail_body::Body::Multipart(ref v) => { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + }, + &mail_body::Body::Mail(ref v) => { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + }, + }; + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let ::std::option::Option::Some(ref v) = self.Body { + match v { + &mail_body::Body::Discrete(ref v) => { + os.write_string(1, v)?; + }, + &mail_body::Body::Multipart(ref v) => { + ::protobuf::rt::write_message_field_with_cached_size(2, v, os)?; + }, + &mail_body::Body::Mail(ref v) => { + ::protobuf::rt::write_message_field_with_cached_size(3, v, os)?; + }, + }; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> MailBody { + MailBody::new() + } + + fn clear(&mut self) { + self.Body = ::std::option::Option::None; + self.Body = ::std::option::Option::None; + self.Body = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static MailBody { + static instance: MailBody = MailBody { + Body: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for MailBody { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("MailBody").unwrap()).clone() + } +} + +impl ::std::fmt::Display for MailBody { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MailBody { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; +} + +/// Nested message and enums of message `MailBody` +pub mod mail_body { + + #[derive(Clone,PartialEq,Debug)] + #[non_exhaustive] + // @@protoc_insertion_point(oneof:jwebmail.MailBody.Body) + pub enum Body { + // @@protoc_insertion_point(oneof_field:jwebmail.MailBody.discrete) + Discrete(::std::string::String), + // @@protoc_insertion_point(oneof_field:jwebmail.MailBody.multipart) + Multipart(Multipart), + // @@protoc_insertion_point(oneof_field:jwebmail.MailBody.mail) + Mail(super::Mail), + } + + impl ::protobuf::Oneof for Body { + } + + impl ::protobuf::OneofFull for Body { + fn descriptor() -> ::protobuf::reflect::OneofDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::OneofDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| <super::MailBody as ::protobuf::MessageFull>::descriptor().oneof_by_name("Body").unwrap()).clone() + } + } + + impl Body { + pub(in super) fn generated_oneof_descriptor_data() -> ::protobuf::reflect::GeneratedOneofDescriptorData { + ::protobuf::reflect::GeneratedOneofDescriptorData::new::<Body>("Body") + } + } + // @@protoc_insertion_point(message:jwebmail.MailBody.Multipart) + #[derive(PartialEq,Clone,Default,Debug)] + pub struct Multipart { + // message fields + // @@protoc_insertion_point(field:jwebmail.MailBody.Multipart.preamble) + pub preamble: ::std::option::Option<::std::string::String>, + // @@protoc_insertion_point(field:jwebmail.MailBody.Multipart.parts) + pub parts: ::std::vec::Vec<super::MIMEPart>, + // @@protoc_insertion_point(field:jwebmail.MailBody.Multipart.epilogue) + pub epilogue: ::std::option::Option<::std::string::String>, + // special fields + // @@protoc_insertion_point(special_field:jwebmail.MailBody.Multipart.special_fields) + pub special_fields: ::protobuf::SpecialFields, + } + + impl<'a> ::std::default::Default for &'a Multipart { + fn default() -> &'a Multipart { + <Multipart as ::protobuf::Message>::default_instance() + } + } + + impl Multipart { + pub fn new() -> Multipart { + ::std::default::Default::default() + } + + pub(in super) fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(3); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "preamble", + |m: &Multipart| { &m.preamble }, + |m: &mut Multipart| { &mut m.preamble }, + )); + fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( + "parts", + |m: &Multipart| { &m.parts }, + |m: &mut Multipart| { &mut m.parts }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "epilogue", + |m: &Multipart| { &m.epilogue }, + |m: &mut Multipart| { &mut m.epilogue }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<Multipart>( + "MailBody.Multipart", + fields, + oneofs, + ) + } + } + + impl ::protobuf::Message for Multipart { + const NAME: &'static str = "Multipart"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.preamble = ::std::option::Option::Some(is.read_string()?); + }, + 18 => { + self.parts.push(is.read_message()?); + }, + 26 => { + self.epilogue = ::std::option::Option::Some(is.read_string()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.preamble.as_ref() { + my_size += ::protobuf::rt::string_size(1, &v); + } + for value in &self.parts { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + }; + if let Some(v) = self.epilogue.as_ref() { + my_size += ::protobuf::rt::string_size(3, &v); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.preamble.as_ref() { + os.write_string(1, v)?; + } + for v in &self.parts { + ::protobuf::rt::write_message_field_with_cached_size(2, v, os)?; + }; + if let Some(v) = self.epilogue.as_ref() { + os.write_string(3, v)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> Multipart { + Multipart::new() + } + + fn clear(&mut self) { + self.preamble = ::std::option::Option::None; + self.parts.clear(); + self.epilogue = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static Multipart { + static instance: Multipart = Multipart { + preamble: ::std::option::Option::None, + parts: ::std::vec::Vec::new(), + epilogue: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } + } + + impl ::protobuf::MessageFull for Multipart { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| super::file_descriptor().message_by_package_relative_name("MailBody.Multipart").unwrap()).clone() + } + } + + impl ::std::fmt::Display for Multipart { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } + } + + impl ::protobuf::reflect::ProtobufValue for Multipart { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; + } +} + +// @@protoc_insertion_point(message:jwebmail.Mail) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct Mail { + // message fields + // @@protoc_insertion_point(field:jwebmail.Mail.head) + pub head: ::protobuf::MessageField<MailHeader>, + // @@protoc_insertion_point(field:jwebmail.Mail.body) + pub body: ::protobuf::MessageField<MailBody>, + // special fields + // @@protoc_insertion_point(special_field:jwebmail.Mail.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a Mail { + fn default() -> &'a Mail { + <Mail as ::protobuf::Message>::default_instance() + } +} + +impl Mail { + pub fn new() -> Mail { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(2); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, MailHeader>( + "head", + |m: &Mail| { &m.head }, + |m: &mut Mail| { &mut m.head }, + )); + fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, MailBody>( + "body", + |m: &Mail| { &m.body }, + |m: &mut Mail| { &mut m.body }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<Mail>( + "Mail", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for Mail { + const NAME: &'static str = "Mail"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + ::protobuf::rt::read_singular_message_into_field(is, &mut self.head)?; + }, + 18 => { + ::protobuf::rt::read_singular_message_into_field(is, &mut self.body)?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.head.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + } + if let Some(v) = self.body.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.head.as_ref() { + ::protobuf::rt::write_message_field_with_cached_size(1, v, os)?; + } + if let Some(v) = self.body.as_ref() { + ::protobuf::rt::write_message_field_with_cached_size(2, v, os)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> Mail { + Mail::new() + } + + fn clear(&mut self) { + self.head.clear(); + self.body.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static Mail { + static instance: Mail = Mail { + head: ::protobuf::MessageField::none(), + body: ::protobuf::MessageField::none(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for Mail { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("Mail").unwrap()).clone() + } +} + +impl ::std::fmt::Display for Mail { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Mail { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; +} + +// @@protoc_insertion_point(message:jwebmail.MIMEPart) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct MIMEPart { + // message fields + // @@protoc_insertion_point(field:jwebmail.MIMEPart.mime_header) + pub mime_header: ::protobuf::MessageField<MIMEHeader>, + // @@protoc_insertion_point(field:jwebmail.MIMEPart.body) + pub body: ::protobuf::MessageField<MailBody>, + // special fields + // @@protoc_insertion_point(special_field:jwebmail.MIMEPart.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a MIMEPart { + fn default() -> &'a MIMEPart { + <MIMEPart as ::protobuf::Message>::default_instance() + } +} + +impl MIMEPart { + pub fn new() -> MIMEPart { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(2); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, MIMEHeader>( + "mime_header", + |m: &MIMEPart| { &m.mime_header }, + |m: &mut MIMEPart| { &mut m.mime_header }, + )); + fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, MailBody>( + "body", + |m: &MIMEPart| { &m.body }, + |m: &mut MIMEPart| { &mut m.body }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<MIMEPart>( + "MIMEPart", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for MIMEPart { + const NAME: &'static str = "MIMEPart"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + ::protobuf::rt::read_singular_message_into_field(is, &mut self.mime_header)?; + }, + 18 => { + ::protobuf::rt::read_singular_message_into_field(is, &mut self.body)?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.mime_header.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + } + if let Some(v) = self.body.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.mime_header.as_ref() { + ::protobuf::rt::write_message_field_with_cached_size(1, v, os)?; + } + if let Some(v) = self.body.as_ref() { + ::protobuf::rt::write_message_field_with_cached_size(2, v, os)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> MIMEPart { + MIMEPart::new() + } + + fn clear(&mut self) { + self.mime_header.clear(); + self.body.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static MIMEPart { + static instance: MIMEPart = MIMEPart { + mime_header: ::protobuf::MessageField::none(), + body: ::protobuf::MessageField::none(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for MIMEPart { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("MIMEPart").unwrap()).clone() + } +} + +impl ::std::fmt::Display for MIMEPart { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MIMEPart { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; +} + +// @@protoc_insertion_point(message:jwebmail.ListReq) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct ListReq { + // message fields + // @@protoc_insertion_point(field:jwebmail.ListReq.folder) + pub folder: ::std::string::String, + // @@protoc_insertion_point(field:jwebmail.ListReq.start) + pub start: i32, + // @@protoc_insertion_point(field:jwebmail.ListReq.end) + pub end: i32, + // @@protoc_insertion_point(field:jwebmail.ListReq.sort) + pub sort: ::std::string::String, + // special fields + // @@protoc_insertion_point(special_field:jwebmail.ListReq.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a ListReq { + fn default() -> &'a ListReq { + <ListReq as ::protobuf::Message>::default_instance() + } +} + +impl ListReq { + pub fn new() -> ListReq { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(4); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "folder", + |m: &ListReq| { &m.folder }, + |m: &mut ListReq| { &mut m.folder }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "start", + |m: &ListReq| { &m.start }, + |m: &mut ListReq| { &mut m.start }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "end", + |m: &ListReq| { &m.end }, + |m: &mut ListReq| { &mut m.end }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "sort", + |m: &ListReq| { &m.sort }, + |m: &mut ListReq| { &mut m.sort }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<ListReq>( + "ListReq", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for ListReq { + const NAME: &'static str = "ListReq"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.folder = is.read_string()?; + }, + 16 => { + self.start = is.read_int32()?; + }, + 24 => { + self.end = is.read_int32()?; + }, + 34 => { + self.sort = is.read_string()?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if !self.folder.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.folder); + } + if self.start != 0 { + my_size += ::protobuf::rt::int32_size(2, self.start); + } + if self.end != 0 { + my_size += ::protobuf::rt::int32_size(3, self.end); + } + if !self.sort.is_empty() { + my_size += ::protobuf::rt::string_size(4, &self.sort); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if !self.folder.is_empty() { + os.write_string(1, &self.folder)?; + } + if self.start != 0 { + os.write_int32(2, self.start)?; + } + if self.end != 0 { + os.write_int32(3, self.end)?; + } + if !self.sort.is_empty() { + os.write_string(4, &self.sort)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> ListReq { + ListReq::new() + } + + fn clear(&mut self) { + self.folder.clear(); + self.start = 0; + self.end = 0; + self.sort.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static ListReq { + static instance: ListReq = ListReq { + folder: ::std::string::String::new(), + start: 0, + end: 0, + sort: ::std::string::String::new(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for ListReq { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("ListReq").unwrap()).clone() + } +} + +impl ::std::fmt::Display for ListReq { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for ListReq { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; +} + +// @@protoc_insertion_point(message:jwebmail.ListResp) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct ListResp { + // message fields + // @@protoc_insertion_point(field:jwebmail.ListResp.mail_heads) + pub mail_heads: ::std::vec::Vec<ListMailHeader>, + // special fields + // @@protoc_insertion_point(special_field:jwebmail.ListResp.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a ListResp { + fn default() -> &'a ListResp { + <ListResp as ::protobuf::Message>::default_instance() + } +} + +impl ListResp { + pub fn new() -> ListResp { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(1); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( + "mail_heads", + |m: &ListResp| { &m.mail_heads }, + |m: &mut ListResp| { &mut m.mail_heads }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<ListResp>( + "ListResp", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for ListResp { + const NAME: &'static str = "ListResp"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.mail_heads.push(is.read_message()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + for value in &self.mail_heads { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + for v in &self.mail_heads { + ::protobuf::rt::write_message_field_with_cached_size(1, v, os)?; + }; + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> ListResp { + ListResp::new() + } + + fn clear(&mut self) { + self.mail_heads.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static ListResp { + static instance: ListResp = ListResp { + mail_heads: ::std::vec::Vec::new(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for ListResp { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("ListResp").unwrap()).clone() + } +} + +impl ::std::fmt::Display for ListResp { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for ListResp { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; +} + +// @@protoc_insertion_point(message:jwebmail.StatsReq) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct StatsReq { + // message fields + // @@protoc_insertion_point(field:jwebmail.StatsReq.folder) + pub folder: ::std::string::String, + // special fields + // @@protoc_insertion_point(special_field:jwebmail.StatsReq.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a StatsReq { + fn default() -> &'a StatsReq { + <StatsReq as ::protobuf::Message>::default_instance() + } +} + +impl StatsReq { + pub fn new() -> StatsReq { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(1); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "folder", + |m: &StatsReq| { &m.folder }, + |m: &mut StatsReq| { &mut m.folder }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<StatsReq>( + "StatsReq", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for StatsReq { + const NAME: &'static str = "StatsReq"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.folder = is.read_string()?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if !self.folder.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.folder); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if !self.folder.is_empty() { + os.write_string(1, &self.folder)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> StatsReq { + StatsReq::new() + } + + fn clear(&mut self) { + self.folder.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static StatsReq { + static instance: StatsReq = StatsReq { + folder: ::std::string::String::new(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for StatsReq { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("StatsReq").unwrap()).clone() + } +} + +impl ::std::fmt::Display for StatsReq { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for StatsReq { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; +} + +// @@protoc_insertion_point(message:jwebmail.StatsResp) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct StatsResp { + // message fields + // @@protoc_insertion_point(field:jwebmail.StatsResp.mail_count) + pub mail_count: u32, + // @@protoc_insertion_point(field:jwebmail.StatsResp.unread_count) + pub unread_count: u32, + // @@protoc_insertion_point(field:jwebmail.StatsResp.byte_size) + pub byte_size: u64, + // special fields + // @@protoc_insertion_point(special_field:jwebmail.StatsResp.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a StatsResp { + fn default() -> &'a StatsResp { + <StatsResp as ::protobuf::Message>::default_instance() + } +} + +impl StatsResp { + pub fn new() -> StatsResp { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(3); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "mail_count", + |m: &StatsResp| { &m.mail_count }, + |m: &mut StatsResp| { &mut m.mail_count }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "unread_count", + |m: &StatsResp| { &m.unread_count }, + |m: &mut StatsResp| { &mut m.unread_count }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "byte_size", + |m: &StatsResp| { &m.byte_size }, + |m: &mut StatsResp| { &mut m.byte_size }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<StatsResp>( + "StatsResp", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for StatsResp { + const NAME: &'static str = "StatsResp"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 8 => { + self.mail_count = is.read_uint32()?; + }, + 16 => { + self.unread_count = is.read_uint32()?; + }, + 24 => { + self.byte_size = is.read_uint64()?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if self.mail_count != 0 { + my_size += ::protobuf::rt::uint32_size(1, self.mail_count); + } + if self.unread_count != 0 { + my_size += ::protobuf::rt::uint32_size(2, self.unread_count); + } + if self.byte_size != 0 { + my_size += ::protobuf::rt::uint64_size(3, self.byte_size); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if self.mail_count != 0 { + os.write_uint32(1, self.mail_count)?; + } + if self.unread_count != 0 { + os.write_uint32(2, self.unread_count)?; + } + if self.byte_size != 0 { + os.write_uint64(3, self.byte_size)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> StatsResp { + StatsResp::new() + } + + fn clear(&mut self) { + self.mail_count = 0; + self.unread_count = 0; + self.byte_size = 0; + self.special_fields.clear(); + } + + fn default_instance() -> &'static StatsResp { + static instance: StatsResp = StatsResp { + mail_count: 0, + unread_count: 0, + byte_size: 0, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for StatsResp { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("StatsResp").unwrap()).clone() + } +} + +impl ::std::fmt::Display for StatsResp { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for StatsResp { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; +} + +// @@protoc_insertion_point(message:jwebmail.ShowReq) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct ShowReq { + // message fields + // @@protoc_insertion_point(field:jwebmail.ShowReq.folder) + pub folder: ::std::string::String, + // @@protoc_insertion_point(field:jwebmail.ShowReq.mid) + pub mid: ::std::string::String, + // special fields + // @@protoc_insertion_point(special_field:jwebmail.ShowReq.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a ShowReq { + fn default() -> &'a ShowReq { + <ShowReq as ::protobuf::Message>::default_instance() + } +} + +impl ShowReq { + pub fn new() -> ShowReq { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(2); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "folder", + |m: &ShowReq| { &m.folder }, + |m: &mut ShowReq| { &mut m.folder }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "mid", + |m: &ShowReq| { &m.mid }, + |m: &mut ShowReq| { &mut m.mid }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<ShowReq>( + "ShowReq", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for ShowReq { + const NAME: &'static str = "ShowReq"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.folder = is.read_string()?; + }, + 18 => { + self.mid = is.read_string()?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if !self.folder.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.folder); + } + if !self.mid.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.mid); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if !self.folder.is_empty() { + os.write_string(1, &self.folder)?; + } + if !self.mid.is_empty() { + os.write_string(2, &self.mid)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> ShowReq { + ShowReq::new() + } + + fn clear(&mut self) { + self.folder.clear(); + self.mid.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static ShowReq { + static instance: ShowReq = ShowReq { + folder: ::std::string::String::new(), + mid: ::std::string::String::new(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for ShowReq { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("ShowReq").unwrap()).clone() + } +} + +impl ::std::fmt::Display for ShowReq { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for ShowReq { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; +} + +// @@protoc_insertion_point(message:jwebmail.ShowResp) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct ShowResp { + // message fields + // @@protoc_insertion_point(field:jwebmail.ShowResp.mail) + pub mail: ::protobuf::MessageField<Mail>, + // special fields + // @@protoc_insertion_point(special_field:jwebmail.ShowResp.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a ShowResp { + fn default() -> &'a ShowResp { + <ShowResp as ::protobuf::Message>::default_instance() + } +} + +impl ShowResp { + pub fn new() -> ShowResp { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(1); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, Mail>( + "mail", + |m: &ShowResp| { &m.mail }, + |m: &mut ShowResp| { &mut m.mail }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<ShowResp>( + "ShowResp", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for ShowResp { + const NAME: &'static str = "ShowResp"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + ::protobuf::rt::read_singular_message_into_field(is, &mut self.mail)?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.mail.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.mail.as_ref() { + ::protobuf::rt::write_message_field_with_cached_size(1, v, os)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> ShowResp { + ShowResp::new() + } + + fn clear(&mut self) { + self.mail.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static ShowResp { + static instance: ShowResp = ShowResp { + mail: ::protobuf::MessageField::none(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for ShowResp { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("ShowResp").unwrap()).clone() + } +} + +impl ::std::fmt::Display for ShowResp { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for ShowResp { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; +} + +// @@protoc_insertion_point(message:jwebmail.RawReq) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct RawReq { + // message fields + // @@protoc_insertion_point(field:jwebmail.RawReq.folder) + pub folder: ::std::string::String, + // @@protoc_insertion_point(field:jwebmail.RawReq.mid) + pub mid: ::std::string::String, + // @@protoc_insertion_point(field:jwebmail.RawReq.path) + pub path: ::std::option::Option<::std::string::String>, + // special fields + // @@protoc_insertion_point(special_field:jwebmail.RawReq.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a RawReq { + fn default() -> &'a RawReq { + <RawReq as ::protobuf::Message>::default_instance() + } +} + +impl RawReq { + pub fn new() -> RawReq { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(3); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "folder", + |m: &RawReq| { &m.folder }, + |m: &mut RawReq| { &mut m.folder }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "mid", + |m: &RawReq| { &m.mid }, + |m: &mut RawReq| { &mut m.mid }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "path", + |m: &RawReq| { &m.path }, + |m: &mut RawReq| { &mut m.path }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<RawReq>( + "RawReq", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for RawReq { + const NAME: &'static str = "RawReq"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.folder = is.read_string()?; + }, + 18 => { + self.mid = is.read_string()?; + }, + 26 => { + self.path = ::std::option::Option::Some(is.read_string()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if !self.folder.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.folder); + } + if !self.mid.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.mid); + } + if let Some(v) = self.path.as_ref() { + my_size += ::protobuf::rt::string_size(3, &v); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if !self.folder.is_empty() { + os.write_string(1, &self.folder)?; + } + if !self.mid.is_empty() { + os.write_string(2, &self.mid)?; + } + if let Some(v) = self.path.as_ref() { + os.write_string(3, v)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> RawReq { + RawReq::new() + } + + fn clear(&mut self) { + self.folder.clear(); + self.mid.clear(); + self.path = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static RawReq { + static instance: RawReq = RawReq { + folder: ::std::string::String::new(), + mid: ::std::string::String::new(), + path: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for RawReq { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("RawReq").unwrap()).clone() + } +} + +impl ::std::fmt::Display for RawReq { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RawReq { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; +} + +// @@protoc_insertion_point(message:jwebmail.RawResp) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct RawResp { + // message fields + // @@protoc_insertion_point(field:jwebmail.RawResp.header) + pub header: ::protobuf::MessageField<MIMEHeader>, + // @@protoc_insertion_point(field:jwebmail.RawResp.body) + pub body: ::std::vec::Vec<u8>, + // special fields + // @@protoc_insertion_point(special_field:jwebmail.RawResp.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a RawResp { + fn default() -> &'a RawResp { + <RawResp as ::protobuf::Message>::default_instance() + } +} + +impl RawResp { + pub fn new() -> RawResp { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(2); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, MIMEHeader>( + "header", + |m: &RawResp| { &m.header }, + |m: &mut RawResp| { &mut m.header }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "body", + |m: &RawResp| { &m.body }, + |m: &mut RawResp| { &mut m.body }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<RawResp>( + "RawResp", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for RawResp { + const NAME: &'static str = "RawResp"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + ::protobuf::rt::read_singular_message_into_field(is, &mut self.header)?; + }, + 18 => { + self.body = is.read_bytes()?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.header.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + } + if !self.body.is_empty() { + my_size += ::protobuf::rt::bytes_size(2, &self.body); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.header.as_ref() { + ::protobuf::rt::write_message_field_with_cached_size(1, v, os)?; + } + if !self.body.is_empty() { + os.write_bytes(2, &self.body)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> RawResp { + RawResp::new() + } + + fn clear(&mut self) { + self.header.clear(); + self.body.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static RawResp { + static instance: RawResp = RawResp { + header: ::protobuf::MessageField::none(), + body: ::std::vec::Vec::new(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for RawResp { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("RawResp").unwrap()).clone() + } +} + +impl ::std::fmt::Display for RawResp { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RawResp { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; +} + +// @@protoc_insertion_point(message:jwebmail.SearchReq) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct SearchReq { + // message fields + // @@protoc_insertion_point(field:jwebmail.SearchReq.folder) + pub folder: ::std::string::String, + // @@protoc_insertion_point(field:jwebmail.SearchReq.pattern) + pub pattern: ::std::string::String, + // special fields + // @@protoc_insertion_point(special_field:jwebmail.SearchReq.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a SearchReq { + fn default() -> &'a SearchReq { + <SearchReq as ::protobuf::Message>::default_instance() + } +} + +impl SearchReq { + pub fn new() -> SearchReq { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(2); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "folder", + |m: &SearchReq| { &m.folder }, + |m: &mut SearchReq| { &mut m.folder }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "pattern", + |m: &SearchReq| { &m.pattern }, + |m: &mut SearchReq| { &mut m.pattern }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<SearchReq>( + "SearchReq", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for SearchReq { + const NAME: &'static str = "SearchReq"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.folder = is.read_string()?; + }, + 18 => { + self.pattern = is.read_string()?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if !self.folder.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.folder); + } + if !self.pattern.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.pattern); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if !self.folder.is_empty() { + os.write_string(1, &self.folder)?; + } + if !self.pattern.is_empty() { + os.write_string(2, &self.pattern)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> SearchReq { + SearchReq::new() + } + + fn clear(&mut self) { + self.folder.clear(); + self.pattern.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static SearchReq { + static instance: SearchReq = SearchReq { + folder: ::std::string::String::new(), + pattern: ::std::string::String::new(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for SearchReq { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("SearchReq").unwrap()).clone() + } +} + +impl ::std::fmt::Display for SearchReq { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for SearchReq { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; +} + +// @@protoc_insertion_point(message:jwebmail.SearchResp) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct SearchResp { + // message fields + // @@protoc_insertion_point(field:jwebmail.SearchResp.found) + pub found: ::std::vec::Vec<ListMailHeader>, + // special fields + // @@protoc_insertion_point(special_field:jwebmail.SearchResp.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a SearchResp { + fn default() -> &'a SearchResp { + <SearchResp as ::protobuf::Message>::default_instance() + } +} + +impl SearchResp { + pub fn new() -> SearchResp { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(1); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( + "found", + |m: &SearchResp| { &m.found }, + |m: &mut SearchResp| { &mut m.found }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<SearchResp>( + "SearchResp", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for SearchResp { + const NAME: &'static str = "SearchResp"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.found.push(is.read_message()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + for value in &self.found { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + for v in &self.found { + ::protobuf::rt::write_message_field_with_cached_size(1, v, os)?; + }; + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> SearchResp { + SearchResp::new() + } + + fn clear(&mut self) { + self.found.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static SearchResp { + static instance: SearchResp = SearchResp { + found: ::std::vec::Vec::new(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for SearchResp { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("SearchResp").unwrap()).clone() + } +} + +impl ::std::fmt::Display for SearchResp { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for SearchResp { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; +} + +// @@protoc_insertion_point(message:jwebmail.FoldersReq) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct FoldersReq { + // special fields + // @@protoc_insertion_point(special_field:jwebmail.FoldersReq.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a FoldersReq { + fn default() -> &'a FoldersReq { + <FoldersReq as ::protobuf::Message>::default_instance() + } +} + +impl FoldersReq { + pub fn new() -> FoldersReq { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(0); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<FoldersReq>( + "FoldersReq", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for FoldersReq { + const NAME: &'static str = "FoldersReq"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> FoldersReq { + FoldersReq::new() + } + + fn clear(&mut self) { + self.special_fields.clear(); + } + + fn default_instance() -> &'static FoldersReq { + static instance: FoldersReq = FoldersReq { + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for FoldersReq { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("FoldersReq").unwrap()).clone() + } +} + +impl ::std::fmt::Display for FoldersReq { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for FoldersReq { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; +} + +// @@protoc_insertion_point(message:jwebmail.FoldersResp) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct FoldersResp { + // message fields + // @@protoc_insertion_point(field:jwebmail.FoldersResp.folders) + pub folders: ::std::vec::Vec<::std::string::String>, + // special fields + // @@protoc_insertion_point(special_field:jwebmail.FoldersResp.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a FoldersResp { + fn default() -> &'a FoldersResp { + <FoldersResp as ::protobuf::Message>::default_instance() + } +} + +impl FoldersResp { + pub fn new() -> FoldersResp { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(1); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( + "folders", + |m: &FoldersResp| { &m.folders }, + |m: &mut FoldersResp| { &mut m.folders }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<FoldersResp>( + "FoldersResp", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for FoldersResp { + const NAME: &'static str = "FoldersResp"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.folders.push(is.read_string()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + for value in &self.folders { + my_size += ::protobuf::rt::string_size(1, &value); + }; + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + for v in &self.folders { + os.write_string(1, &v)?; + }; + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> FoldersResp { + FoldersResp::new() + } + + fn clear(&mut self) { + self.folders.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static FoldersResp { + static instance: FoldersResp = FoldersResp { + folders: ::std::vec::Vec::new(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for FoldersResp { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("FoldersResp").unwrap()).clone() + } +} + +impl ::std::fmt::Display for FoldersResp { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for FoldersResp { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; +} + +// @@protoc_insertion_point(message:jwebmail.MoveReq) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct MoveReq { + // message fields + // @@protoc_insertion_point(field:jwebmail.MoveReq.mid) + pub mid: ::std::string::String, + // @@protoc_insertion_point(field:jwebmail.MoveReq.from_f) + pub from_f: ::std::string::String, + // @@protoc_insertion_point(field:jwebmail.MoveReq.to_f) + pub to_f: ::std::string::String, + // special fields + // @@protoc_insertion_point(special_field:jwebmail.MoveReq.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a MoveReq { + fn default() -> &'a MoveReq { + <MoveReq as ::protobuf::Message>::default_instance() + } +} + +impl MoveReq { + pub fn new() -> MoveReq { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(3); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "mid", + |m: &MoveReq| { &m.mid }, + |m: &mut MoveReq| { &mut m.mid }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "from_f", + |m: &MoveReq| { &m.from_f }, + |m: &mut MoveReq| { &mut m.from_f }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "to_f", + |m: &MoveReq| { &m.to_f }, + |m: &mut MoveReq| { &mut m.to_f }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<MoveReq>( + "MoveReq", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for MoveReq { + const NAME: &'static str = "MoveReq"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.mid = is.read_string()?; + }, + 18 => { + self.from_f = is.read_string()?; + }, + 26 => { + self.to_f = is.read_string()?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if !self.mid.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.mid); + } + if !self.from_f.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.from_f); + } + if !self.to_f.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.to_f); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if !self.mid.is_empty() { + os.write_string(1, &self.mid)?; + } + if !self.from_f.is_empty() { + os.write_string(2, &self.from_f)?; + } + if !self.to_f.is_empty() { + os.write_string(3, &self.to_f)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> MoveReq { + MoveReq::new() + } + + fn clear(&mut self) { + self.mid.clear(); + self.from_f.clear(); + self.to_f.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static MoveReq { + static instance: MoveReq = MoveReq { + mid: ::std::string::String::new(), + from_f: ::std::string::String::new(), + to_f: ::std::string::String::new(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for MoveReq { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("MoveReq").unwrap()).clone() + } +} + +impl ::std::fmt::Display for MoveReq { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MoveReq { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; +} + +// @@protoc_insertion_point(message:jwebmail.MoveResp) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct MoveResp { + // special fields + // @@protoc_insertion_point(special_field:jwebmail.MoveResp.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a MoveResp { + fn default() -> &'a MoveResp { + <MoveResp as ::protobuf::Message>::default_instance() + } +} + +impl MoveResp { + pub fn new() -> MoveResp { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(0); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<MoveResp>( + "MoveResp", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for MoveResp { + const NAME: &'static str = "MoveResp"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> MoveResp { + MoveResp::new() + } + + fn clear(&mut self) { + self.special_fields.clear(); + } + + fn default_instance() -> &'static MoveResp { + static instance: MoveResp = MoveResp { + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for MoveResp { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("MoveResp").unwrap()).clone() + } +} + +impl ::std::fmt::Display for MoveResp { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MoveResp { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; +} + +// @@protoc_insertion_point(message:jwebmail.RemoveReq) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct RemoveReq { + // message fields + // @@protoc_insertion_point(field:jwebmail.RemoveReq.folder) + pub folder: ::std::string::String, + // @@protoc_insertion_point(field:jwebmail.RemoveReq.mid) + pub mid: ::std::string::String, + // special fields + // @@protoc_insertion_point(special_field:jwebmail.RemoveReq.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a RemoveReq { + fn default() -> &'a RemoveReq { + <RemoveReq as ::protobuf::Message>::default_instance() + } +} + +impl RemoveReq { + pub fn new() -> RemoveReq { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(2); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "folder", + |m: &RemoveReq| { &m.folder }, + |m: &mut RemoveReq| { &mut m.folder }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "mid", + |m: &RemoveReq| { &m.mid }, + |m: &mut RemoveReq| { &mut m.mid }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<RemoveReq>( + "RemoveReq", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for RemoveReq { + const NAME: &'static str = "RemoveReq"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.folder = is.read_string()?; + }, + 18 => { + self.mid = is.read_string()?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if !self.folder.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.folder); + } + if !self.mid.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.mid); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if !self.folder.is_empty() { + os.write_string(1, &self.folder)?; + } + if !self.mid.is_empty() { + os.write_string(2, &self.mid)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> RemoveReq { + RemoveReq::new() + } + + fn clear(&mut self) { + self.folder.clear(); + self.mid.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static RemoveReq { + static instance: RemoveReq = RemoveReq { + folder: ::std::string::String::new(), + mid: ::std::string::String::new(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for RemoveReq { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("RemoveReq").unwrap()).clone() + } +} + +impl ::std::fmt::Display for RemoveReq { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RemoveReq { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; +} + +// @@protoc_insertion_point(message:jwebmail.RemoveResp) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct RemoveResp { + // special fields + // @@protoc_insertion_point(special_field:jwebmail.RemoveResp.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a RemoveResp { + fn default() -> &'a RemoveResp { + <RemoveResp as ::protobuf::Message>::default_instance() + } +} + +impl RemoveResp { + pub fn new() -> RemoveResp { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(0); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<RemoveResp>( + "RemoveResp", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for RemoveResp { + const NAME: &'static str = "RemoveResp"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> RemoveResp { + RemoveResp::new() + } + + fn clear(&mut self) { + self.special_fields.clear(); + } + + fn default_instance() -> &'static RemoveResp { + static instance: RemoveResp = RemoveResp { + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for RemoveResp { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("RemoveResp").unwrap()).clone() + } +} + +impl ::std::fmt::Display for RemoveResp { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RemoveResp { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x0ejwebmail.proto\x12\x08jwebmail\"\xb7\x02\n\nMIMEHeader\x12\x1a\n\ + \x08maintype\x18\x01\x20\x01(\tR\x08maintype\x12\x18\n\x07subtype\x18\ + \x02\x20\x01(\tR\x07subtype\x12K\n\x0ccontentdispo\x18\x03\x20\x01(\x0e2\ + '.jwebmail.MIMEHeader.ContentDispositionR\x0ccontentdispo\x12\x20\n\tfil\ + e_name\x18\x04\x20\x01(\tH\0R\x08fileName\x88\x01\x01\"v\n\x12ContentDis\ + position\x12\x1c\n\x18CONTENT_DISPOSITION_NONE\x10\0\x12\x1e\n\x1aCONTEN\ + T_DISPOSITION_INLINE\x10\x01\x12\"\n\x1eCONTENT_DISPOSITION_ATTACHMENT\ + \x10\x02B\x0c\n\n_file_name\"\xc8\x04\n\nMailHeader\x12\x1b\n\tsend_date\ + \x18\x01\x20\x01(\tR\x08sendDate\x12@\n\x0cwritten_from\x18\x02\x20\x03(\ + \x0b2\x1d.jwebmail.MailHeader.MailAddrR\x0bwrittenFrom\x12:\n\x06sender\ + \x18\x03\x20\x01(\x0b2\x1d.jwebmail.MailHeader.MailAddrH\0R\x06sender\ + \x88\x01\x01\x128\n\x08reply_to\x18\x04\x20\x03(\x0b2\x1d.jwebmail.MailH\ + eader.MailAddrR\x07replyTo\x126\n\x07send_to\x18\x05\x20\x03(\x0b2\x1d.j\ + webmail.MailHeader.MailAddrR\x06sendTo\x12-\n\x02cc\x18\x06\x20\x03(\x0b\ + 2\x1d.jwebmail.MailHeader.MailAddrR\x02cc\x12/\n\x03bcc\x18\x07\x20\x03(\ + \x0b2\x1d.jwebmail.MailHeader.MailAddrR\x03bcc\x12\x18\n\x07subject\x18\ + \x08\x20\x01(\tR\x07subject\x12\x1a\n\x08comments\x18\t\x20\x03(\tR\x08c\ + omments\x12\x1a\n\x08keywords\x18\n\x20\x03(\tR\x08keywords\x12(\n\x04mi\ + me\x18\x0b\x20\x01(\x0b2\x14.jwebmail.MIMEHeaderR\x04mime\x1aF\n\x08Mail\ + Addr\x12\x17\n\x04name\x18\x01\x20\x01(\tH\0R\x04name\x88\x01\x01\x12\ + \x18\n\x07address\x18\x02\x20\x01(\tR\x07addressB\x07\n\x05_nameB\t\n\ + \x07_sender\"\xa0\x01\n\x0eListMailHeader\x12\x1b\n\tbyte_size\x18\x01\ + \x20\x01(\x04R\x08byteSize\x12\x16\n\x06unread\x18\x02\x20\x01(\x08R\x06\ + unread\x12\x19\n\x08rec_date\x18\x03\x20\x01(\tR\x07recDate\x12\x10\n\ + \x03mid\x18\x04\x20\x01(\tR\x03mid\x12,\n\x06header\x18\x05\x20\x01(\x0b\ + 2\x14.jwebmail.MailHeaderR\x06header\"\xa8\x02\n\x08MailBody\x12\x1c\n\ + \x08discrete\x18\x01\x20\x01(\tH\0R\x08discrete\x12<\n\tmultipart\x18\ + \x02\x20\x01(\x0b2\x1c.jwebmail.MailBody.MultipartH\0R\tmultipart\x12$\n\ + \x04mail\x18\x03\x20\x01(\x0b2\x0e.jwebmail.MailH\0R\x04mail\x1a\x91\x01\ + \n\tMultipart\x12\x1f\n\x08preamble\x18\x01\x20\x01(\tH\0R\x08preamble\ + \x88\x01\x01\x12(\n\x05parts\x18\x02\x20\x03(\x0b2\x12.jwebmail.MIMEPart\ + R\x05parts\x12\x1f\n\x08epilogue\x18\x03\x20\x01(\tH\x01R\x08epilogue\ + \x88\x01\x01B\x0b\n\t_preambleB\x0b\n\t_epilogueB\x06\n\x04Body\"X\n\x04\ + Mail\x12(\n\x04head\x18\x01\x20\x01(\x0b2\x14.jwebmail.MailHeaderR\x04he\ + ad\x12&\n\x04body\x18\x02\x20\x01(\x0b2\x12.jwebmail.MailBodyR\x04body\"\ + i\n\x08MIMEPart\x125\n\x0bmime_header\x18\x01\x20\x01(\x0b2\x14.jwebmail\ + .MIMEHeaderR\nmimeHeader\x12&\n\x04body\x18\x02\x20\x01(\x0b2\x12.jwebma\ + il.MailBodyR\x04body\"]\n\x07ListReq\x12\x16\n\x06folder\x18\x01\x20\x01\ + (\tR\x06folder\x12\x14\n\x05start\x18\x02\x20\x01(\x05R\x05start\x12\x10\ + \n\x03end\x18\x03\x20\x01(\x05R\x03end\x12\x12\n\x04sort\x18\x04\x20\x01\ + (\tR\x04sort\"C\n\x08ListResp\x127\n\nmail_heads\x18\x01\x20\x03(\x0b2\ + \x18.jwebmail.ListMailHeaderR\tmailHeads\"\"\n\x08StatsReq\x12\x16\n\x06\ + folder\x18\x01\x20\x01(\tR\x06folder\"j\n\tStatsResp\x12\x1d\n\nmail_cou\ + nt\x18\x01\x20\x01(\rR\tmailCount\x12!\n\x0cunread_count\x18\x02\x20\x01\ + (\rR\x0bunreadCount\x12\x1b\n\tbyte_size\x18\x03\x20\x01(\x04R\x08byteSi\ + ze\"3\n\x07ShowReq\x12\x16\n\x06folder\x18\x01\x20\x01(\tR\x06folder\x12\ + \x10\n\x03mid\x18\x02\x20\x01(\tR\x03mid\".\n\x08ShowResp\x12\"\n\x04mai\ + l\x18\x01\x20\x01(\x0b2\x0e.jwebmail.MailR\x04mail\"T\n\x06RawReq\x12\ + \x16\n\x06folder\x18\x01\x20\x01(\tR\x06folder\x12\x10\n\x03mid\x18\x02\ + \x20\x01(\tR\x03mid\x12\x17\n\x04path\x18\x03\x20\x01(\tH\0R\x04path\x88\ + \x01\x01B\x07\n\x05_path\"K\n\x07RawResp\x12,\n\x06header\x18\x01\x20\ + \x01(\x0b2\x14.jwebmail.MIMEHeaderR\x06header\x12\x12\n\x04body\x18\x02\ + \x20\x01(\x0cR\x04body\"=\n\tSearchReq\x12\x16\n\x06folder\x18\x01\x20\ + \x01(\tR\x06folder\x12\x18\n\x07pattern\x18\x02\x20\x01(\tR\x07pattern\"\ + <\n\nSearchResp\x12.\n\x05found\x18\x01\x20\x03(\x0b2\x18.jwebmail.ListM\ + ailHeaderR\x05found\"\x0c\n\nFoldersReq\"'\n\x0bFoldersResp\x12\x18\n\ + \x07folders\x18\x01\x20\x03(\tR\x07folders\"E\n\x07MoveReq\x12\x10\n\x03\ + mid\x18\x01\x20\x01(\tR\x03mid\x12\x15\n\x06from_f\x18\x02\x20\x01(\tR\ + \x05fromF\x12\x11\n\x04to_f\x18\x03\x20\x01(\tR\x03toF\"\n\n\x08MoveResp\ + \"5\n\tRemoveReq\x12\x16\n\x06folder\x18\x01\x20\x01(\tR\x06folder\x12\ + \x10\n\x03mid\x18\x02\x20\x01(\tR\x03mid\"\x0c\n\nRemoveResp2\x9a\x03\n\ + \x0bMailService\x12-\n\x04List\x12\x11.jwebmail.ListReq\x1a\x12.jwebmail\ + .ListResp\x120\n\x05Stats\x12\x12.jwebmail.StatsReq\x1a\x13.jwebmail.Sta\ + tsResp\x12-\n\x04Show\x12\x11.jwebmail.ShowReq\x1a\x12.jwebmail.ShowResp\ + \x12*\n\x03Raw\x12\x10.jwebmail.RawReq\x1a\x11.jwebmail.RawResp\x123\n\ + \x06Search\x12\x13.jwebmail.SearchReq\x1a\x14.jwebmail.SearchResp\x126\n\ + \x07Folders\x12\x14.jwebmail.FoldersReq\x1a\x15.jwebmail.FoldersResp\x12\ + -\n\x04Move\x12\x11.jwebmail.MoveReq\x1a\x12.jwebmail.MoveResp\x123\n\ + \x06Remove\x12\x13.jwebmail.RemoveReq\x1a\x14.jwebmail.RemoveRespb\x06pr\ + oto3\ +"; + +/// `FileDescriptorProto` object which was a source for this generated file +fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + static file_descriptor_proto_lazy: ::protobuf::rt::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::Lazy::new(); + file_descriptor_proto_lazy.get(|| { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() + }) +} + +/// `FileDescriptor` object which allows dynamic access to files +pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor { + static generated_file_descriptor_lazy: ::protobuf::rt::Lazy<::protobuf::reflect::GeneratedFileDescriptor> = ::protobuf::rt::Lazy::new(); + static file_descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::FileDescriptor> = ::protobuf::rt::Lazy::new(); + file_descriptor.get(|| { + let generated_file_descriptor = generated_file_descriptor_lazy.get(|| { + let mut deps = ::std::vec::Vec::with_capacity(0); + let mut messages = ::std::vec::Vec::with_capacity(24); + messages.push(MIMEHeader::generated_message_descriptor_data()); + messages.push(MailHeader::generated_message_descriptor_data()); + messages.push(ListMailHeader::generated_message_descriptor_data()); + messages.push(MailBody::generated_message_descriptor_data()); + messages.push(Mail::generated_message_descriptor_data()); + messages.push(MIMEPart::generated_message_descriptor_data()); + messages.push(ListReq::generated_message_descriptor_data()); + messages.push(ListResp::generated_message_descriptor_data()); + messages.push(StatsReq::generated_message_descriptor_data()); + messages.push(StatsResp::generated_message_descriptor_data()); + messages.push(ShowReq::generated_message_descriptor_data()); + messages.push(ShowResp::generated_message_descriptor_data()); + messages.push(RawReq::generated_message_descriptor_data()); + messages.push(RawResp::generated_message_descriptor_data()); + messages.push(SearchReq::generated_message_descriptor_data()); + messages.push(SearchResp::generated_message_descriptor_data()); + messages.push(FoldersReq::generated_message_descriptor_data()); + messages.push(FoldersResp::generated_message_descriptor_data()); + messages.push(MoveReq::generated_message_descriptor_data()); + messages.push(MoveResp::generated_message_descriptor_data()); + messages.push(RemoveReq::generated_message_descriptor_data()); + messages.push(RemoveResp::generated_message_descriptor_data()); + messages.push(mail_header::MailAddr::generated_message_descriptor_data()); + messages.push(mail_body::Multipart::generated_message_descriptor_data()); + let mut enums = ::std::vec::Vec::with_capacity(1); + enums.push(mimeheader::ContentDisposition::generated_enum_descriptor_data()); + ::protobuf::reflect::GeneratedFileDescriptor::new_generated( + file_descriptor_proto(), + deps, + messages, + enums, + ) + }); + ::protobuf::reflect::FileDescriptor::new_generated_2(generated_file_descriptor) + }) +} diff --git a/src/pb3/mod.rs b/src/pb3/mod.rs new file mode 100644 index 0000000..55a7aae --- /dev/null +++ b/src/pb3/mod.rs @@ -0,0 +1,3 @@ +// @generated + +pub mod jwebmail; diff --git a/src/rfc822.rs b/src/rfc822.rs index 6944715..aafedde 100644 --- a/src/rfc822.rs +++ b/src/rfc822.rs @@ -1,30 +1,14 @@ -use chrono::{DateTime, NaiveDateTime, Utc}; +use chrono::NaiveDateTime; use mailparse::{addrparse_header, body::Body, dateparse, DispositionType, ParsedMail}; -use serde::{ser::SerializeSeq, Serialize, Serializer}; -use crate::error::Error; +use crate::error::{Error, Result}; +use crate::pb3::jwebmail::mimeheader::ContentDisposition::*; +use crate::pb3::jwebmail::{ + mail_body::Multipart, mail_header::MailAddr, ListMailHeader, MIMEHeader, MIMEPart, Mail, + MailBody, MailHeader, +}; -#[derive(Serialize, Eq, Ord, Debug)] -pub struct MailAddr { - pub display_name: String, - pub address: String, -} - -impl PartialEq for MailAddr { - fn eq(&self, r: &Self) -> bool { - self.address == r.address - } -} - -impl PartialOrd for MailAddr { - fn partial_cmp(&self, r: &Self) -> Option<std::cmp::Ordering> { - Some(self.cmp(r)) - } -} - -fn parse_mail_addrs( - inp: &mailparse::MailHeader, -) -> Result<Vec<MailAddr>, mailparse::MailParseError> { +fn parse_mail_addrs(inp: &mailparse::MailHeader) -> Result<Vec<MailAddr>> { let mut mal = addrparse_header(inp)?; Ok(mal @@ -33,136 +17,25 @@ fn parse_mail_addrs( mailparse::MailAddr::Group(mut g) => g .addrs .drain(..) - .map(|s| MailAddr { - display_name: s.display_name.unwrap_or_default(), - address: s.addr, + .map(|s| { + let mut r = MailAddr::new(); + r.name = Some(s.display_name.unwrap_or_default()); + r.address = s.addr; + r }) .collect(), - mailparse::MailAddr::Single(s) => vec![MailAddr { - display_name: s.display_name.unwrap_or_default(), - address: s.addr, - }], + mailparse::MailAddr::Single(s) => { + let mut addr = MailAddr::new(); + addr.name = Some(s.display_name.unwrap_or_default()); + addr.address = s.addr; + vec![addr] + } }) .collect()) } // ---------------- -fn serialize_date_time<S>(dt: &DateTime<Utc>, s: S) -> Result<S::Ok, S::Error> -where - S: Serializer, -{ - s.serialize_str(&dt.to_rfc3339()) -} - -fn serialize_sender<S>(oma: &Option<MailAddr>, s: S) -> Result<S::Ok, S::Error> -where - S: Serializer, -{ - if let Some(ma) = oma { - let mut seq = s.serialize_seq(Some(1))?; - seq.serialize_element(ma)?; - seq.end() - } else { - let seq = s.serialize_seq(Some(0))?; - seq.end() - } -} - -#[derive(Serialize, Debug)] -pub struct MailHeader { - #[serde(serialize_with = "serialize_date_time")] - #[serde(rename = "date")] - pub orig_date: DateTime<Utc>, - - // originator fields - pub from: Vec<MailAddr>, - #[serde(skip_serializing_if = "Option::is_none")] - #[serde(serialize_with = "serialize_sender")] - pub sender: Option<MailAddr>, - #[serde(skip_serializing_if = "Option::is_none")] - reply_to: Option<Vec<MailAddr>>, - - // destination fields - #[serde(skip_serializing_if = "Vec::is_empty")] - to: Vec<MailAddr>, - #[serde(skip_serializing_if = "Vec::is_empty")] - cc: Vec<MailAddr>, - #[serde(skip_serializing_if = "Option::is_none")] - bcc: Option<Vec<MailAddr>>, - - /* identification fields - #[serde(skip_serializing_if = "String::is_empty")] - message_id: String, - #[serde(skip_serializing_if = "Option::is_none")] - in_reply_to: Option<String>, - #[serde(skip_serializing_if = "Option::is_none")] - references: Option<String>, - */ - // informational fields - pub subject: String, - #[serde(skip_serializing_if = "Vec::is_empty")] - comments: Vec<String>, - #[serde(skip_serializing_if = "Vec::is_empty")] - keywords: Vec<String>, - - mime: MIMEHeader, -} - -#[derive(Serialize, Debug)] -pub struct MIMEHeader { - #[serde(rename = "content_maintype")] - pub maintype: String, - #[serde(rename = "content_subtype")] - pub subtype: String, - #[serde(skip_serializing_if = "String::is_empty")] - pub content_disposition: String, - #[serde(skip_serializing_if = "String::is_empty")] - pub filename: String, -} - -enum ContentDisposition { - None, - Inline, - Attachment { filename: Option<String> }, -} - -#[derive(Serialize)] -pub struct MIMEPart { - pub head: MIMEHeader, - body: MailBody, -} - -#[derive(Serialize)] -#[serde(untagged)] -pub enum MailBody { - Discrete(String), - Multipart { - #[serde(skip_serializing_if = "String::is_empty")] - preamble: String, - parts: Vec<MIMEPart>, - #[serde(skip_serializing_if = "String::is_empty")] - epilogue: String, - }, - Message(Box<Mail>), -} - -#[derive(Serialize)] -pub struct Mail { - head: MailHeader, - pub body: MailBody, -} - -#[derive(Serialize, Debug)] -pub struct TopMailHeader { - byte_size: u64, - unread: bool, - #[serde(serialize_with = "serialize_date_time")] - pub date_received: DateTime<Utc>, - message_handle: String, - pub head: MailHeader, -} - fn get_received(me: &mut maildir::MailEntry) -> i64 { me.received().unwrap_or_else(|_| { let mut id = me.id(); @@ -171,29 +44,22 @@ fn get_received(me: &mut maildir::MailEntry) -> i64 { }) } -impl TryFrom<maildir::MailEntry> for TopMailHeader { - type Error = Error; - - fn try_from(mut me: maildir::MailEntry) -> Result<Self, Self::Error> { - Ok(TopMailHeader { - byte_size: me.path().metadata()?.len(), - unread: !me.is_seen(), - date_received: NaiveDateTime::from_timestamp_opt(get_received(&mut me), 0) - .unwrap() - .and_utc(), - message_handle: me.id().to_owned(), - head: parse_mail_header(&me.parsed()?)?, - }) - } +pub fn me_to_lmh(mut me: maildir::MailEntry) -> Result<ListMailHeader> { + let mut lmh = ListMailHeader::new(); + lmh.byte_size = me.path().metadata()?.len(); + lmh.unread = !me.is_seen(); + lmh.rec_date = NaiveDateTime::from_timestamp_opt(get_received(&mut me), 0) + .unwrap() + .and_utc() + .to_rfc3339(); + lmh.mid = me.id().to_owned(); + lmh.header = Some(parse_mail_header(&me.parsed()?)?).into(); + + Ok(lmh) } -pub fn parse_mail_content(v: &ParsedMail) -> Result<MIMEHeader, maildir::MailEntryError> { - let mut c = MIMEHeader { - maintype: String::new(), - subtype: String::new(), - content_disposition: String::new(), - filename: String::new(), - }; +pub fn parse_mail_content(v: &ParsedMail) -> Result<MIMEHeader> { + let mut c = MIMEHeader::new(); { let mut val = v.ctype.mimetype.clone(); @@ -207,11 +73,11 @@ pub fn parse_mail_content(v: &ParsedMail) -> Result<MIMEHeader, maildir::MailEnt } match v.get_content_disposition().disposition { - DispositionType::Inline => c.content_disposition = "inline".to_owned(), + DispositionType::Inline => c.contentdispo = CONTENT_DISPOSITION_INLINE.into(), DispositionType::Attachment => { - c.content_disposition = "attachment".to_owned(); + c.contentdispo = CONTENT_DISPOSITION_ATTACHMENT.into(); if let Some(fname) = v.get_content_disposition().params.remove("filename") { - c.filename = fname; + c.file_name = Some(fname).into(); } } _ => {} @@ -225,7 +91,7 @@ pub fn parse_mail_content(v: &ParsedMail) -> Result<MIMEHeader, maildir::MailEnt match key.as_ref() { "filename" => { - c.filename = val; + c.file_name = Some(val).into(); } _ => {} } @@ -234,27 +100,11 @@ pub fn parse_mail_content(v: &ParsedMail) -> Result<MIMEHeader, maildir::MailEnt Ok(c) } -fn parse_mail_header(pm: &ParsedMail) -> Result<MailHeader, maildir::MailEntryError> { +fn parse_mail_header(pm: &ParsedMail) -> Result<MailHeader> { let v = &pm.headers; - let mut mh = MailHeader { - orig_date: Utc::now(), - from: Vec::new(), - sender: None, - reply_to: None, - to: Vec::new(), - cc: Vec::new(), - bcc: None, - subject: String::new(), - comments: Vec::new(), - keywords: Vec::new(), - mime: MIMEHeader { - maintype: String::new(), - subtype: String::new(), - content_disposition: String::new(), - filename: String::new(), - }, - }; + let mut mh = MailHeader::new(); + let mut mimeh = MIMEHeader::new(); { let mut val = pm.ctype.mimetype.clone(); @@ -262,9 +112,9 @@ fn parse_mail_header(pm: &ParsedMail) -> Result<MailHeader, maildir::MailEntryEr val.truncate(i); } let j = val.find('/').unwrap(); - mh.mime.subtype = val.split_off(j + 1); + mimeh.subtype = val.split_off(j + 1); val.pop(); - mh.mime.maintype = val; + mimeh.maintype = val; } let mut key = String::new(); @@ -277,21 +127,22 @@ fn parse_mail_header(pm: &ParsedMail) -> Result<MailHeader, maildir::MailEntryEr match key.as_str() { "date" => { - mh.orig_date = NaiveDateTime::from_timestamp_opt(dateparse(&val)?, 0) + mh.send_date = NaiveDateTime::from_timestamp_opt(dateparse(&val)?, 0) .unwrap() .and_utc() + .to_rfc3339() } "from" => { - if !mh.from.is_empty() { - return Err("from already set".into()); + if !mh.written_from.is_empty() { + return Err(Error::SortOrder("from already set".into())); } - mh.from = parse_mail_addrs(y)? + mh.written_from = parse_mail_addrs(y)? } - "sender" => mh.sender = parse_mail_addrs(y)?.drain(0..1).next(), - "reply-to" => mh.reply_to = Some(parse_mail_addrs(y)?), - "to" => mh.to = parse_mail_addrs(y)?, + "sender" => mh.sender = parse_mail_addrs(y)?.drain(0..1).next().into(), + "reply-to" => mh.reply_to = parse_mail_addrs(y)?, + "to" => mh.send_to = parse_mail_addrs(y)?, "cc" => mh.cc = parse_mail_addrs(y)?, - "bcc" => mh.bcc = Some(parse_mail_addrs(y)?), + "bcc" => mh.bcc = parse_mail_addrs(y)?, "subject" => { mh.subject = val; } @@ -304,32 +155,42 @@ fn parse_mail_header(pm: &ParsedMail) -> Result<MailHeader, maildir::MailEntryEr "mime-version" => { strip_comments(&mut val); if val.trim() != "1.0" { - return Err(maildir::MailEntryError::DateError("unknown mime version")); + return Err(Error::MailEntryError(maildir::MailEntryError::DateError( + "unknown mime version", + ))); } } "content-disposition" => { - mh.mime.content_disposition = val; + let cd = val.to_ascii_lowercase(); + match cd.as_ref() { + "inline" => mimeh.contentdispo = CONTENT_DISPOSITION_INLINE.into(), + "attachment" => mimeh.contentdispo = CONTENT_DISPOSITION_ATTACHMENT.into(), + _ => {} + }; } "filename" => { - mh.mime.filename = val; + mimeh.file_name = Some(val); } _ => {} }; key.clear(); } - + mh.mime = Some(mimeh).into(); Ok(mh) } -fn parse_mail_body(pm: &ParsedMail) -> Result<MailBody, maildir::MailEntryError> { +fn parse_mail_body(pm: &ParsedMail) -> Result<MailBody> { let body = if pm.ctype.mimetype.starts_with("message/") { - MailBody::Message(Box::new( - mailparse::parse_mail(pm.get_body()?.as_ref())?.try_into()?, - )) + let mut mb = MailBody::new(); + mb.set_mail(parsed_mail_to_mail(mailparse::parse_mail( + pm.get_body()?.as_ref(), + )?)?); + mb } else if pm.subparts.is_empty() && pm.ctype.mimetype.starts_with("text/") { - let b = pm.get_body()?; - MailBody::Discrete(b) + let mut mb = MailBody::new(); + mb.set_discrete(pm.get_body()?); + mb } else if pm.subparts.is_empty() { let b = match pm.get_body_encoded() { Body::Base64(eb) => { @@ -344,23 +205,25 @@ fn parse_mail_body(pm: &ParsedMail) -> Result<MailBody, maildir::MailEntryError> Body::QuotedPrintable(eb) => eb.get_decoded_as_string()?, _ => todo!(), }; - MailBody::Discrete(b) + let mut mb = MailBody::new(); + mb.set_discrete(b); + mb } else { - MailBody::Multipart { - preamble: String::new(), - parts: pm - .subparts - .iter() - .map(|part| { - Ok(MIMEPart { - head: parse_mail_content(part)?, - body: parse_mail_body(part)?, - }) - }) - .filter_map(|p: Result<MIMEPart, maildir::MailEntryError>| p.ok()) - .collect(), - epilogue: String::new(), - } + let mut mb = MailBody::new(); + let mut mp = Multipart::new(); + mp.parts = pm + .subparts + .iter() + .map(|part| -> Result<MIMEPart> { + let mut mp = MIMEPart::new(); + mp.mime_header = Some(parse_mail_content(part)?).into(); + mp.body = Some(parse_mail_body(part)?).into(); + Ok(mp) + }) + .filter_map(|p| p.ok()) + .collect(); + mb.set_multipart(mp); + mb }; Ok(body) } @@ -461,17 +324,15 @@ fn strip_comments(s: &mut String) { } } -impl TryFrom<ParsedMail<'_>> for Mail { - type Error = maildir::MailEntryError; +pub fn parsed_mail_to_mail(pm: ParsedMail) -> Result<Mail> { + let mut m = Mail::new(); + m.head = Some(parse_mail_header(&pm)?).into(); + m.body = Some(parse_mail_body(&pm)?).into(); - fn try_from(m: ParsedMail) -> Result<Self, Self::Error> { - let head = parse_mail_header(&m)?; - let body = parse_mail_body(&m)?; - - Ok(Mail { head, body }) - } + Ok(m) } +/* #[cfg(test)] mod tests { use super::*; @@ -545,3 +406,4 @@ mod tests { } } } +*/ |