From f52a76dba318ffc9b318b1c5d1a54bed87df43bf Mon Sep 17 00:00:00 2001 From: Bill Thiede Date: Mon, 20 Nov 2023 18:38:10 -0800 Subject: [PATCH] Added graphql endpoint and tested with tags implementation. --- Cargo.lock | 407 ++++++++++++++++++++++++++++++++++++--- dev.sh | 2 +- notmuch/src/lib.rs | 5 + server/Cargo.toml | 4 +- server/src/bin/server.rs | 80 +++++++- 5 files changed, 461 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bfc89ff..ab0e6fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,16 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + [[package]] name = "addr2line" version = "0.21.0" @@ -56,6 +66,99 @@ version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +[[package]] +name = "ascii_utils" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71938f30533e4d95a6d17aa530939da3842c2ab6f4f84b9dae68447e4129f74a" + +[[package]] +name = "async-graphql" +version = "6.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "298a5d587d6e6fdb271bf56af2dc325a80eb291fd0fc979146584b9a05494a8c" +dependencies = [ + "async-graphql-derive", + "async-graphql-parser", + "async-graphql-value", + "async-stream", + "async-trait", + "base64 0.13.1", + "bytes", + "fast_chemail", + "fnv", + "futures-util", + "handlebars", + "http", + "indexmap 2.0.0", + "mime 0.3.17", + "multer", + "num-traits", + "once_cell", + "pin-project-lite", + "regex", + "serde", + "serde_json", + "serde_urlencoded", + "static_assertions", + "tempfile", + "thiserror", +] + +[[package]] +name = "async-graphql-derive" +version = "6.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f329c7eb9b646a72f70c9c4b516c70867d356ec46cb00dcac8ad343fd006b0" +dependencies = [ + "Inflector", + "async-graphql-parser", + "darling", + "proc-macro-crate", + "proc-macro2 1.0.66", + "quote 1.0.33", + "strum", + "syn 2.0.29", + "thiserror", +] + +[[package]] +name = "async-graphql-parser" +version = "6.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6139181845757fd6a73fbb8839f3d036d7150b798db0e9bb3c6e83cdd65bd53b" +dependencies = [ + "async-graphql-value", + "pest", + "serde", + "serde_json", +] + +[[package]] +name = "async-graphql-rocket" +version = "6.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10c5004043928e9ea8ca2faecc473e3c4fe4f5be259f63c9d735c9a0e4760c2b" +dependencies = [ + "async-graphql", + "rocket 0.5.0", + "serde", + "serde_json", + "tokio-util", +] + +[[package]] +name = "async-graphql-value" +version = "6.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "323a5143f5bdd2030f45e3f2e0c821c9b1d36e79cf382129c64299c50a7f3750" +dependencies = [ + "bytes", + "indexmap 2.0.0", + "serde", + "serde_json", +] + [[package]] name = "async-stream" version = "0.3.5" @@ -181,6 +284,15 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "bumpalo" version = "3.13.0" @@ -198,6 +310,9 @@ name = "bytes" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +dependencies = [ + "serde", +] [[package]] name = "cc" @@ -289,9 +404,9 @@ dependencies = [ [[package]] name = "cookie" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" +checksum = "3cd91cf61412820176e137621345ee43b3f4423e589e7ae4e50d601d93e35ef8" dependencies = [ "percent-encoding 2.3.0", "time 0.3.28", @@ -304,6 +419,15 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +[[package]] +name = "cpufeatures" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +dependencies = [ + "libc", +] + [[package]] name = "crc32fast" version = "1.3.2" @@ -356,6 +480,16 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + [[package]] name = "css-inline" version = "0.8.5" @@ -417,6 +551,41 @@ dependencies = [ "syn 2.0.29", ] +[[package]] +name = "darling" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2 1.0.66", + "quote 1.0.33", + "strsim", + "syn 2.0.29", +] + +[[package]] +name = "darling_macro" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +dependencies = [ + "darling_core", + "quote 1.0.33", + "syn 2.0.29", +] + [[package]] name = "dbg" version = "1.0.4" @@ -516,6 +685,16 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + [[package]] name = "dtoa" version = "1.0.9" @@ -579,6 +758,15 @@ dependencies = [ "libc", ] +[[package]] +name = "fast_chemail" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "495a39d30d624c2caabe6312bfead73e7717692b44e0b32df168c275a2e8e9e4" +dependencies = [ + "ascii_utils", +] + [[package]] name = "fastrand" version = "2.0.0" @@ -792,6 +980,16 @@ dependencies = [ "windows 0.48.0", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check 0.9.4", +] + [[package]] name = "gethostname" version = "0.2.3" @@ -924,6 +1122,20 @@ dependencies = [ "tracing", ] +[[package]] +name = "handlebars" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faa67bab9ff362228eb3d00bd024a4965d8231bbb7921167f0cfa66c6626b225" +dependencies = [ + "log 0.4.20", + "pest", + "pest_derive", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -936,6 +1148,12 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -1065,6 +1283,12 @@ dependencies = [ "cc", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.1.5" @@ -1100,7 +1324,6 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", - "serde", ] [[package]] @@ -1111,6 +1334,7 @@ checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" dependencies = [ "equivalent", "hashbrown 0.14.0", + "serde", ] [[package]] @@ -1673,6 +1897,51 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +[[package]] +name = "pest" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81d78524685f5ef2a3b3bd1cafbc9fcabb036253d9b1463e726a91cd16e2dfc2" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68bd1206e71118b5356dae5ddc61c8b11e28b09ef6a31acbd15ea48a28e0c227" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2 1.0.66", + "quote 1.0.33", + "syn 2.0.29", +] + +[[package]] +name = "pest_meta" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c747191d4ad9e4a4ab9c8798f1e82a39affe7ef9648390b7e5548d18e099de6" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + [[package]] name = "phf" version = "0.8.0" @@ -1811,6 +2080,16 @@ dependencies = [ "yansi 0.5.1", ] +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit", +] + [[package]] name = "proc-macro-hack" version = "0.5.20+deprecated" @@ -2096,9 +2375,9 @@ dependencies = [ [[package]] name = "rocket" -version = "0.5.0-rc.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58734f7401ae5cfd129685b48f61182331745b357b96f2367f01aebaf1cc9cc9" +checksum = "9e7bb57ccb26670d73b6a47396c83139447b9e7878cab627fdfe9ea8da489150" dependencies = [ "async-stream", "async-trait", @@ -2108,8 +2387,7 @@ dependencies = [ "either", "figment", "futures", - "indexmap 1.9.3", - "is-terminal", + "indexmap 2.0.0", "log 0.4.20", "memchr", "multer", @@ -2118,11 +2396,11 @@ dependencies = [ "pin-project-lite", "rand 0.8.5", "ref-cast", - "rocket_codegen 0.5.0-rc.3", - "rocket_http 0.5.0-rc.3", + "rocket_codegen 0.5.0", + "rocket_http 0.5.0", "serde", "serde_json", - "state 0.5.3", + "state 0.6.0", "tempfile", "time 0.3.28", "tokio", @@ -2130,7 +2408,7 @@ dependencies = [ "tokio-util", "ubyte", "version_check 0.9.4", - "yansi 0.5.1", + "yansi 1.0.0-rc.1", ] [[package]] @@ -2150,18 +2428,19 @@ dependencies = [ [[package]] name = "rocket_codegen" -version = "0.5.0-rc.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7093353f14228c744982e409259fb54878ba9563d08214f2d880d59ff2fc508b" +checksum = "a2238066abf75f21be6cd7dc1a09d5414a671f4246e384e49fe3f8a4936bd04c" dependencies = [ "devise 0.4.1", "glob", - "indexmap 1.9.3", + "indexmap 2.0.0", "proc-macro2 1.0.66", "quote 1.0.33", - "rocket_http 0.5.0-rc.3", + "rocket_http 0.5.0", "syn 2.0.29", "unicode-xid 0.2.4", + "version_check 0.9.4", ] [[package]] @@ -2179,13 +2458,14 @@ dependencies = [ [[package]] name = "rocket_cors" -version = "0.6.0-alpha2" -source = "git+https://github.com/lawliet89/rocket_cors?branch=master#985098dd8f3b052716111eaa872d184cc21a1a68" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfac3a1df83f8d4fc96aa41dba3b86c786417b7fc0f52ec76295df2ba781aa69" dependencies = [ "http", "log 0.4.20", "regex", - "rocket 0.5.0-rc.3", + "rocket 0.5.0", "serde", "serde_derive", "unicase 2.7.0", @@ -2212,16 +2492,16 @@ dependencies = [ [[package]] name = "rocket_http" -version = "0.5.0-rc.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936012c99162a03a67f37f9836d5f938f662e26f2717809761a9ac46432090f4" +checksum = "37a1663694d059fe5f943ea5481363e48050acedd241d46deb2e27f71110389e" dependencies = [ - "cookie 0.17.0", + "cookie 0.18.0", "either", "futures", "http", "hyper 0.14.27", - "indexmap 1.9.3", + "indexmap 2.0.0", "log 0.4.20", "memchr", "pear 0.2.7", @@ -2231,7 +2511,7 @@ dependencies = [ "serde", "smallvec", "stable-pattern", - "state 0.5.3", + "state 0.6.0", "time 0.3.28", "tokio", "uncased", @@ -2429,14 +2709,28 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa 1.0.9", + "ryu", + "serde", +] + [[package]] name = "server" version = "0.1.0" dependencies = [ + "async-graphql", + "async-graphql-rocket", "glog", "log 0.4.20", "notmuch", - "rocket 0.5.0-rc.3", + "rocket 0.5.0", "rocket_contrib", "rocket_cors", "serde", @@ -2457,6 +2751,17 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest", +] + [[package]] name = "sharded-slab" version = "0.1.4" @@ -2559,13 +2864,19 @@ checksum = "3015a7d0a5fd5105c91c3710d42f9ccf0abfb287d62206484dcc67f9569a6483" [[package]] name = "state" -version = "0.5.3" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbe866e1e51e8260c9eed836a042a5e7f6726bb2b411dffeaa712e19c388f23b" +checksum = "2b8c4a4445d81357df8b1a650d0d0d6fbbbfe99d064aa5e02f3e4022061476d8" dependencies = [ "loom", ] +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "string_cache" version = "0.8.7" @@ -2592,6 +2903,34 @@ dependencies = [ "quote 1.0.33", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck", + "proc-macro2 1.0.66", + "quote 1.0.33", + "rustversion", + "syn 2.0.29", +] + [[package]] name = "syn" version = "0.15.44" @@ -2795,6 +3134,7 @@ checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" dependencies = [ "bytes", "futures-core", + "futures-io", "futures-sink", "pin-project-lite", "tokio", @@ -2930,6 +3270,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + [[package]] name = "ubyte" version = "0.10.3" @@ -2939,6 +3285,12 @@ dependencies = [ "serde", ] +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + [[package]] name = "uncased" version = "0.9.9" @@ -3422,3 +3774,6 @@ name = "yansi" version = "1.0.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1367295b8f788d371ce2dbc842c7b709c73ee1364d30351dd300ec2203b12377" +dependencies = [ + "is-terminal", +] diff --git a/dev.sh b/dev.sh index 8cbc86e..7b34b04 100755 --- a/dev.sh +++ b/dev.sh @@ -3,5 +3,5 @@ tmux new-session -d -s letterbox-dev tmux rename-window web tmux send-keys "cd web; trunk serve -w ../shared -w ../notmuch -w ./" C-m tmux new-window -n server -tmux send-keys "cd server; cargo watch -x run -w ../shared -w ../notmuch -w ./" C-m +tmux send-keys "cd server; cargo watch -c -x run -w ../shared -w ../notmuch -w ./" C-m tmux attach -d -t letterbox-dev diff --git a/notmuch/src/lib.rs b/notmuch/src/lib.rs index f746267..f39b742 100644 --- a/notmuch/src/lib.rs +++ b/notmuch/src/lib.rs @@ -480,6 +480,11 @@ impl Notmuch { self.run_notmuch(std::iter::empty::<&str>()) } + pub fn tags(&self) -> Result, NotmuchError> { + let res = self.run_notmuch(["search", "--format=json", "--output=tags", "*"])?; + Ok(serde_json::from_slice(&res)?) + } + pub fn search( &self, query: &str, diff --git a/server/Cargo.toml b/server/Cargo.toml index 3544b5e..1fc7951 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -8,7 +8,6 @@ default-bin = "server" [dependencies] rocket = { version = "0.5.0-rc.2", features = [ "json" ] } -rocket_cors = { git = "https://github.com/lawliet89/rocket_cors", branch = "master" } notmuch = { path = "../notmuch" } shared = { path = "../shared" } serde_json = "1.0.87" @@ -18,6 +17,9 @@ log = "0.4.17" tokio = "1.26.0" glog = "0.1.0" urlencoding = "2.1.3" +async-graphql = "6.0.11" +async-graphql-rocket = "6.0.11" +rocket_cors = "0.6.0" [dependencies.rocket_contrib] version = "0.4.11" diff --git a/server/src/bin/server.rs b/server/src/bin/server.rs index dd54328..96b6200 100644 --- a/server/src/bin/server.rs +++ b/server/src/bin/server.rs @@ -1,14 +1,24 @@ #[macro_use] extern crate rocket; -use std::{error::Error, io::Cursor, str::FromStr}; +use std::{ + error::Error, + hash::{DefaultHasher, Hash, Hasher}, + io::Cursor, + str::FromStr, +}; +use async_graphql::{ + http::GraphiQLSource, Context, EmptyMutation, EmptySubscription, FieldResult, Object, Schema, + SimpleObject, +}; +use async_graphql_rocket::{GraphQLQuery, GraphQLRequest, GraphQLResponse}; use glog::Flags; use notmuch::{Notmuch, NotmuchError, ThreadSet}; use rocket::{ http::{ContentType, Header}, request::Request, - response::{Debug, Responder}, + response::{content, Debug, Responder}, serde::json::Json, Response, State, }; @@ -16,11 +26,6 @@ use rocket_cors::{AllowedHeaders, AllowedOrigins}; use server::{error::ServerError, nm::threadset_to_messages}; use shared::Message; -#[get("/")] -fn hello() -> &'static str { - "Hello, world!" -} - #[get("/refresh")] async fn refresh(nm: &State) -> Result, Debug> { Ok(Json(String::from_utf8_lossy(&nm.new()?).to_string())) @@ -125,6 +130,56 @@ async fn original( Ok((ContentType::Plain, res)) } +#[rocket::get("/")] +fn graphiql() -> content::RawHtml { + content::RawHtml(GraphiQLSource::build().endpoint("/graphql").finish()) +} + +#[rocket::get("/graphql?")] +async fn graphql_query(schema: &State, query: GraphQLQuery) -> GraphQLResponse { + query.execute(schema.inner()).await +} + +#[rocket::post("/graphql", data = "", format = "application/json")] +async fn graphql_request( + schema: &State, + request: GraphQLRequest, +) -> GraphQLResponse { + request.execute(schema.inner()).await +} + +pub struct QueryRoot; + +#[derive(SimpleObject)] +struct Tag { + name: String, + fg_color: String, + bg_color: String, +} + +#[Object] +impl QueryRoot { + async fn tags<'ctx>(&self, ctx: &Context<'ctx>) -> FieldResult> { + let nm = ctx.data_unchecked::(); + Ok(nm + .tags()? + .into_iter() + .map(|tag| { + let mut hasher = DefaultHasher::new(); + tag.hash(&mut hasher); + let hex = format!("#{:06x}", hasher.finish() % (1 << 24)); + Tag { + name: tag, + fg_color: "white".to_string(), + bg_color: hex, + } + }) + .collect()) + } +} + +pub type GraphqlSchema = Schema; + #[rocket::main] async fn main() -> Result<(), Box> { glog::new() @@ -148,21 +203,28 @@ async fn main() -> Result<(), Box> { } .to_cors()?; + let schema = Schema::build(QueryRoot, EmptyMutation, EmptySubscription) + .data(Notmuch::default()) + .finish(); + let _ = rocket::build() .mount( "/", routes![ original_part, original, - hello, refresh, search_all, search, show_pretty, - show + show, + graphql_query, + graphql_request, + graphiql ], ) .attach(cors) + .manage(schema) .manage(Notmuch::default()) //.manage(Notmuch::with_config("../notmuch/testdata/notmuch.config")) .launch()