Compare commits

..

No commits in common. "2da67487b5d19dfb9469b0e17153a76e3d739a76" and "c7d9cf0a69d8d33d7dbb719951df61baa1235fca" have entirely different histories.

9 changed files with 538 additions and 358 deletions

2
.gitignore vendored
View File

@ -1,3 +1,3 @@
/target /target
*.sw* *.swp
tests/data tests/data

384
Cargo.lock generated
View File

@ -2,6 +2,16 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 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]] [[package]]
name = "aead" name = "aead"
version = "0.3.2" version = "0.3.2"
@ -67,6 +77,15 @@ dependencies = [
"version_check", "version_check",
] ]
[[package]]
name = "aho-corasick"
version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.55" version = "1.0.55"
@ -85,6 +104,12 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "ascii_utils"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71938f30533e4d95a6d17aa530939da3842c2ab6f4f84b9dae68447e4129f74a"
[[package]] [[package]]
name = "async-attributes" name = "async-attributes"
version = "1.1.2" version = "1.1.2"
@ -146,6 +171,76 @@ dependencies = [
"once_cell", "once_cell",
] ]
[[package]]
name = "async-graphql"
version = "4.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffffea596a12b6d9ea5c6fc8a5f414cf4e0c8cd6b618ac2c3d4f56d9b5c5520b"
dependencies = [
"async-graphql-derive",
"async-graphql-parser",
"async-graphql-value",
"async-stream",
"async-trait",
"bytes",
"fast_chemail",
"fnv",
"futures-util",
"http",
"indexmap",
"mime",
"multer",
"num-traits",
"once_cell",
"pin-project-lite 0.2.8",
"regex",
"serde",
"serde_json",
"static_assertions",
"tempfile",
"thiserror",
]
[[package]]
name = "async-graphql-derive"
version = "4.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7082221cc1dc29edec0e3225420146b1fbc7f18ba534e301eab186501ae84c28"
dependencies = [
"Inflector",
"async-graphql-parser",
"darling",
"proc-macro-crate",
"proc-macro2",
"quote",
"syn",
"thiserror",
]
[[package]]
name = "async-graphql-parser"
version = "4.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c328e2cb0dade64333859f7a7e22c9e19a3767afaad673976a1d855c9bda5ffa"
dependencies = [
"async-graphql-value",
"pest",
"serde",
"serde_json",
]
[[package]]
name = "async-graphql-value"
version = "4.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "005292494ce718604a0dc1531e5827fe540761e1df44b064085711c5fde70b7c"
dependencies = [
"bytes",
"indexmap",
"serde",
"serde_json",
]
[[package]] [[package]]
name = "async-h1" name = "async-h1"
version = "2.3.3" version = "2.3.3"
@ -280,6 +375,27 @@ dependencies = [
"wasm-bindgen-futures", "wasm-bindgen-futures",
] ]
[[package]]
name = "async-stream"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e"
dependencies = [
"async-stream-impl",
"futures-core",
]
[[package]]
name = "async-stream-impl"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "async-task" name = "async-task"
version = "4.1.0" version = "4.1.0"
@ -419,6 +535,15 @@ version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "bytes"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "cache-padded" name = "cache-padded"
version = "1.2.0" version = "1.2.0"
@ -587,6 +712,41 @@ dependencies = [
"cipher", "cipher",
] ]
[[package]]
name = "darling"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4529658bdda7fd6769b8614be250cdcfc3aeb0ee72fe66f9e41e5e5eb73eac02"
dependencies = [
"darling_core",
"darling_macro",
]
[[package]]
name = "darling_core"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "649c91bc01e8b1eac09fb91e8dbc7d517684ca6be8ebc75bb9cafc894f9fdb6f"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn",
]
[[package]]
name = "darling_macro"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddfc69c5bfcbd2fc09a0f38451d2daf0e372e367986a83906d1b0dbc88134fb5"
dependencies = [
"darling_core",
"quote",
"syn",
]
[[package]] [[package]]
name = "dashmap" name = "dashmap"
version = "4.0.2" version = "4.0.2"
@ -597,19 +757,6 @@ dependencies = [
"num_cpus", "num_cpus",
] ]
[[package]]
name = "dashmap"
version = "5.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc"
dependencies = [
"cfg-if 1.0.0",
"hashbrown",
"lock_api",
"once_cell",
"parking_lot_core",
]
[[package]] [[package]]
name = "digest" name = "digest"
version = "0.8.1" version = "0.8.1"
@ -640,6 +787,15 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257"
[[package]]
name = "encoding_rs"
version = "0.8.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b"
dependencies = [
"cfg-if 1.0.0",
]
[[package]] [[package]]
name = "event-listener" name = "event-listener"
version = "2.5.2" version = "2.5.2"
@ -652,6 +808,15 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
[[package]]
name = "fast_chemail"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "495a39d30d624c2caabe6312bfead73e7717692b44e0b32df168c275a2e8e9e4"
dependencies = [
"ascii_utils",
]
[[package]] [[package]]
name = "fastrand" name = "fastrand"
version = "1.7.0" version = "1.7.0"
@ -677,6 +842,12 @@ dependencies = [
"web-sys", "web-sys",
] ]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]] [[package]]
name = "form_urlencoded" name = "form_urlencoded"
version = "1.0.1" version = "1.0.1"
@ -687,21 +858,6 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "futures"
version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]] [[package]]
name = "futures-channel" name = "futures-channel"
version = "0.3.21" version = "0.3.21"
@ -709,7 +865,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-sink",
] ]
[[package]] [[package]]
@ -718,17 +873,6 @@ version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3"
[[package]]
name = "futures-executor"
version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]] [[package]]
name = "futures-io" name = "futures-io"
version = "0.3.21" version = "0.3.21"
@ -763,9 +907,9 @@ dependencies = [
[[package]] [[package]]
name = "futures-sink" name = "futures-sink"
version = "0.3.24" version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56" checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868"
[[package]] [[package]]
name = "futures-task" name = "futures-task"
@ -779,7 +923,6 @@ version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
dependencies = [ dependencies = [
"futures-channel",
"futures-core", "futures-core",
"futures-io", "futures-io",
"futures-macro", "futures-macro",
@ -856,9 +999,9 @@ dependencies = [
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.12.3" version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3"
dependencies = [ dependencies = [
"ahash", "ahash",
] ]
@ -902,6 +1045,17 @@ dependencies = [
"digest 0.9.0", "digest 0.9.0",
] ]
[[package]]
name = "http"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
dependencies = [
"bytes",
"fnv",
"itoa",
]
[[package]] [[package]]
name = "http-client" name = "http-client"
version = "6.5.1" version = "6.5.1"
@ -910,7 +1064,7 @@ checksum = "ea880b03c18a7e981d7fb3608b8904a98425d53c440758fcebf7d934aa56547c"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"cfg-if 1.0.0", "cfg-if 1.0.0",
"dashmap 4.0.2", "dashmap",
"http-types", "http-types",
"log", "log",
] ]
@ -943,6 +1097,12 @@ version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9100414882e15fb7feccb4897e5f0ff0ff1ca7d1a86a23208ada4d7a18e6c6c4" checksum = "9100414882e15fb7feccb4897e5f0ff0ff1ca7d1a86a23208ada4d7a18e6c6c4"
[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]] [[package]]
name = "idna" name = "idna"
version = "0.2.3" version = "0.2.3"
@ -954,6 +1114,17 @@ dependencies = [
"unicode-normalization", "unicode-normalization",
] ]
[[package]]
name = "indexmap"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
dependencies = [
"autocfg",
"hashbrown",
"serde",
]
[[package]] [[package]]
name = "infer" name = "infer"
version = "0.2.3" version = "0.2.3"
@ -1024,9 +1195,9 @@ checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
[[package]] [[package]]
name = "lock_api" name = "lock_api"
version = "0.4.8" version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f80bf5aacaf25cbfc8210d1cfb718f2bf3b11c4c54e5afe36c236853a8ec390" checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"scopeguard", "scopeguard",
@ -1086,14 +1257,34 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
name = "morethantext_web" name = "morethantext_web"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"async-graphql",
"async-std", "async-std",
"config", "config",
"serde", "serde",
"serde_json",
"serial_test", "serial_test",
"tide", "tide",
"tide-testing", "tide-testing",
] ]
[[package]]
name = "multer"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f8f35e687561d5c1667590911e6698a8cb714a134a7505718a182e7bc9d3836"
dependencies = [
"bytes",
"encoding_rs",
"futures-util",
"http",
"httparse",
"log",
"memchr",
"mime",
"spin",
"version_check",
]
[[package]] [[package]]
name = "nom" name = "nom"
version = "7.1.1" version = "7.1.1"
@ -1135,9 +1326,9 @@ dependencies = [
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.13.1" version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e" checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
[[package]] [[package]]
name = "opaque-debug" name = "opaque-debug"
@ -1313,6 +1504,16 @@ version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
[[package]]
name = "proc-macro-crate"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a"
dependencies = [
"thiserror",
"toml",
]
[[package]] [[package]]
name = "proc-macro-error" name = "proc-macro-error"
version = "1.0.4" version = "1.0.4"
@ -1434,13 +1635,39 @@ dependencies = [
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.2.16" version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
dependencies = [ dependencies = [
"bitflags", "bitflags",
] ]
[[package]]
name = "regex"
version = "1.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
[[package]]
name = "remove_dir_all"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
dependencies = [
"winapi",
]
[[package]] [[package]]
name = "ron" name = "ron"
version = "0.7.0" version = "0.7.0"
@ -1477,6 +1704,12 @@ dependencies = [
"semver", "semver",
] ]
[[package]]
name = "rustversion"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f"
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.9" version = "1.0.9"
@ -1560,12 +1793,10 @@ dependencies = [
[[package]] [[package]]
name = "serial_test" name = "serial_test"
version = "0.9.0" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92761393ee4dc3ff8f4af487bd58f4307c9329bbedea02cac0089ad9c411e153" checksum = "d19dbfb999a147cedbfe82f042eb9555f5b0fa4ef95ee4570b74349103d9c9f4"
dependencies = [ dependencies = [
"dashmap 5.4.0",
"futures",
"lazy_static", "lazy_static",
"log", "log",
"parking_lot", "parking_lot",
@ -1574,13 +1805,14 @@ dependencies = [
[[package]] [[package]]
name = "serial_test_derive" name = "serial_test_derive"
version = "0.9.0" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b6f5d1c3087fb119617cff2966fe3808a80e5eb59a8c1601d5994d66f4346a5" checksum = "cb9e2050b2be1d681f8f1c1a528bcfe4e00afa2d8995f713974f5333288659f2"
dependencies = [ dependencies = [
"proc-macro-error", "proc-macro-error",
"proc-macro2", "proc-macro2",
"quote", "quote",
"rustversion",
"syn", "syn",
] ]
@ -1660,9 +1892,9 @@ checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5"
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.9.0" version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
[[package]] [[package]]
name = "socket2" name = "socket2"
@ -1674,6 +1906,12 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "spin"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c530c2b0d0bf8b69304b39fe2001993e267461948b890cd037d8ad4293fa1a0d"
[[package]] [[package]]
name = "standback" name = "standback"
version = "0.2.17" version = "0.2.17"
@ -1683,6 +1921,12 @@ dependencies = [
"version_check", "version_check",
] ]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]] [[package]]
name = "stdweb" name = "stdweb"
version = "0.4.20" version = "0.4.20"
@ -1732,6 +1976,12 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]] [[package]]
name = "subtle" name = "subtle"
version = "2.4.1" version = "2.4.1"
@ -1775,6 +2025,20 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "tempfile"
version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
dependencies = [
"cfg-if 1.0.0",
"fastrand",
"libc",
"redox_syscall",
"remove_dir_all",
"winapi",
]
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.30" version = "1.0.30"

View File

@ -6,10 +6,11 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
#async-graphql = "*" async-graphql = "*"
async-std = { version = "*", features = ["attributes"] } async-std = { version = "*", features = ["attributes"] }
config = "*" config = "*"
serde = "*" serde = "*"
serde_json = "*"
tide = "*" tide = "*"
[dev-dependencies] [dev-dependencies]

View File

@ -1,90 +1,195 @@
use std::{error::Error, fmt}; use std::{error::Error, fmt, sync::Arc};
#[derive(Debug)] #[derive(Debug)]
pub struct DBError { pub enum MTTError {
msg: String, Generic(Generic),
src: Option<Box<dyn Error + 'static>>,
} }
impl DBError { impl MTTError {
pub fn new<S>(msg: S) -> Self pub fn new<S>(detail: S) -> Self
where
S: Into<String>,
{
Generic::new(detail).into()
}
pub fn add_source<E>(&mut self, source: E)
where
E: Into<MTTError>,
{
match self {
MTTError::Generic(err) => err.add_source(source),
}
}
}
impl Error for MTTError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
MTTError::Generic(err) => err.source(),
}
}
}
impl fmt::Display for MTTError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
MTTError::Generic(err) => write!(f, "{}", err),
}
}
}
impl From<Generic> for MTTError {
fn from(err: Generic) -> Self {
MTTError::Generic(err)
}
}
#[derive(Debug)]
pub struct Generic {
detail: String,
source: Option<Arc<MTTError>>,
}
impl Generic {
fn new<S>(detail: S) -> Self
where where
S: Into<String>, S: Into<String>,
{ {
Self { Self {
msg: msg.into(), detail: detail.into(),
src: None, source: None,
} }
} }
pub fn add_source<E>(&mut self, src: E) fn add_source<E>(&mut self, source: E)
where where
E: Error + 'static, E: Into<MTTError>,
{ {
self.src = Some(Box::new(src)); self.source = Some(Arc::new(source.into()));
} }
} }
impl Error for DBError { impl Error for Generic {
fn source(&self) -> Option<&(dyn Error + 'static)> { fn source(&self) -> Option<&(dyn Error + 'static)> {
match &self.src { match &self.source {
Some(err) => Some(err.as_ref()), Some(err) => Some(err.as_ref()),
None => None, None => None,
} }
} }
} }
impl fmt::Display for DBError { impl fmt::Display for Generic {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.msg) write!(f, "{}", self.detail)
} }
} }
#[cfg(test)] #[cfg(test)]
mod create { mod mtterror {
use super::*; use super::*;
#[test] #[test]
fn with_str() { fn create_with_str() {
let msg = "something happened"; let detail = "Something";
let err = DBError::new(msg); let err = MTTError::new(detail);
assert!( assert!(
err.to_string() == msg, err.to_string() == detail,
"Got: {} -- Want: {}", "\n\nGot: {}\nWant: {}\n\n",
err.to_string(), err.to_string(),
msg detail
); );
assert!( assert!(
err.source().is_none(), err.source().is_none(),
"Error should initialize with no source." "Error source should initialoze to None."
); );
} }
#[test] #[test]
fn with_string() { fn create_with_string() {
let msg = "it went boom".to_string(); let detail = "massive".to_string();
let err = DBError::new(msg.clone()); let err = MTTError::new(detail.clone());
assert!( assert!(
err.to_string() == msg, err.to_string() == detail,
"Got: {} -- Want: {}", "\n\nGot: {}\nWant: {}\n\n",
err.to_string(), err.to_string(),
msg detail
);
assert!(
err.source().is_none(),
"Error should initialize with no source."
); );
} }
#[test] #[test]
fn with_source() { fn with_source() {
let msg = "but this caused the problem"; let mut err = MTTError::new("the error");
let mut par = DBError::new("parent error"); let detail = "This is the cause";
let src = DBError::new(msg); let src = MTTError::new(detail);
par.add_source(src); err.add_source(src);
let output = par.source(); assert!(
assert!(output.is_some(), "Should return source."); err.source().unwrap().to_string() == detail,
let source = output.unwrap(); "/n/nGot: {}\nWant: {}\n\n",
assert!(source.to_string() == msg); err.source().unwrap().to_string(),
detail
);
}
}
#[cfg(test)]
mod generic {
use super::*;
#[test]
fn create_with_str() {
let detail = "new error";
let err = Generic::new(detail);
assert!(
err.to_string() == detail,
"\n\nGot: {}\nWant: {}\n\n",
err.to_string(),
detail
);
assert!(
err.source().is_none(),
"Error source should initialoze to None."
);
let error: MTTError = err.into();
assert!(
error.to_string() == detail,
"\n\nGot: {}\nWant: {}\n\n",
error.to_string(),
detail
);
}
#[test]
fn create_with_string() {
let detail = "some error".to_string();
let err = Generic::new(detail.clone());
assert!(
err.to_string() == detail,
"\n\nGot: {}\nWant: {}\n\n",
err.to_string(),
detail
);
}
#[test]
fn with_source() {
let par_detail = "parent error";
let cld_detail = "child error";
let par_err = Generic::new(par_detail);
let mut cld_err = Generic::new(cld_detail);
cld_err.add_source(par_err);
assert!(
cld_err.source().unwrap().to_string() == par_detail,
"/n/nGot: {}\nWant: {}\n\n",
cld_err.source().unwrap().to_string(),
par_detail
);
let error: MTTError = cld_err.into();
assert!(
error.source().unwrap().to_string() == par_detail,
"/n/nGot: {}\nWant: {}\n\n",
error.source().unwrap().to_string(),
par_detail
);
} }
} }

View File

@ -1,29 +1,13 @@
use std::fmt;
mod static_string; mod static_string;
use crate::morethantext::error::MTTError;
use static_string::StaticString; use static_string::StaticString;
use std::fmt;
pub enum FieldType { pub enum FieldType {
StaticString(StaticString), StaticString(StaticString),
} }
impl FieldType {
fn new(ftype: &str, data: &str) -> Result<Self, MTTError> {
let field = match ftype {
"StaticString" => StaticString::new(data),
_ => Err(MTTError::new(format!(
"field type {} does not exist",
ftype
))),
};
match field {
Ok(fld) => Ok(fld.into()),
Err(e) => Err(e),
}
}
}
impl fmt::Display for FieldType { impl fmt::Display for FieldType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
@ -45,7 +29,7 @@ mod converstion {
#[test] #[test]
fn from_static_string() { fn from_static_string() {
let data = "a static string"; let data = "a static string";
let field = StaticString::new(data).unwrap(); let field = StaticString::new(data);
let ftype: FieldType = field.into(); let ftype: FieldType = field.into();
assert!( assert!(
ftype.to_string() == data, ftype.to_string() == data,
@ -54,36 +38,4 @@ mod converstion {
data data
); );
} }
#[test]
fn bad_field_type() -> Result<(), String> {
let field_type = "dragon";
let err_msg = format!("field type {} does not exist", field_type);
match FieldType::new(field_type, "marmalade") {
Ok(_) => Err("Should have returned an error.".to_string()),
Err(err) => {
if err.to_string() == err_msg {
Ok(())
} else {
Err(format!(
"Error message is incorrect: Got: '{}' Want: '{}'",
err.to_string(),
err_msg
))
}
}
}
}
#[test]
fn new_static_string() {
let data = "This is a test.";
let field = FieldType::new("StaticString", data).unwrap();
assert!(
field.to_string() == data,
"\n\nGot: {}\nWant: {}\n\n",
field.to_string(),
data
);
}
} }

View File

@ -1,4 +1,3 @@
use crate::morethantext::error::MTTError;
use std::fmt; use std::fmt;
pub struct StaticString { pub struct StaticString {
@ -6,11 +5,11 @@ pub struct StaticString {
} }
impl StaticString { impl StaticString {
pub fn new<S>(name: S) -> Result<Self, MTTError> pub fn new<S>(name: S) -> Self
where where
S: Into<String>, S: Into<String>,
{ {
Ok(Self { data: name.into() }) Self { data: name.into() }
} }
} }
@ -27,7 +26,7 @@ mod creation {
#[test] #[test]
fn new_accepts_str() { fn new_accepts_str() {
let data = "some data"; let data = "some data";
let field = StaticString::new(data).unwrap(); let field = StaticString::new(data);
assert!( assert!(
field.to_string() == data, field.to_string() == data,
"\n\nGot: {}\nWant: {}", "\n\nGot: {}\nWant: {}",
@ -39,7 +38,7 @@ mod creation {
#[test] #[test]
fn new_accepts_string() { fn new_accepts_string() {
let data = "actual string"; let data = "actual string";
let field = StaticString::new(data.to_string()).unwrap(); let field = StaticString::new(data.to_string());
assert!( assert!(
field.to_string() == data, field.to_string() == data,
"\n\nGot: {}\nWant: {}", "\n\nGot: {}\nWant: {}",

View File

@ -1,135 +1,120 @@
pub mod error; pub mod error;
use async_std::sync::{Arc, RwLock}; use async_std::sync::{Arc, RwLock};
use error::DBError; use error::MTTError;
use std::collections::HashMap; use std::collections::HashMap;
#[derive(Clone)] #[derive(Clone)]
pub struct MoreThanText { pub struct MoreThanText {
databases: Arc<RwLock<HashMap<String, Database>>>, tables: Arc<RwLock<HashMap<String, Table>>>,
} }
impl MoreThanText { impl MoreThanText {
pub async fn new() -> Self { pub async fn new() -> Self {
Self { Self {
databases: Arc::new(RwLock::new(HashMap::new())), tables: Arc::new(RwLock::new(HashMap::new())),
} }
} }
async fn create_database(&self, name: &str) -> Result<(), DBError> { pub async fn new_table<S>(&self, tname: S) -> Result<Table, MTTError>
let mut databases = self.databases.write().await; where
match databases.get(name) { S: Into<String>,
Some(_) => Err(DBError::new("duplicate database name")), {
let mut tables = self.tables.write().await;
let name = tname.into();
match tables.get(&name) {
Some(_) => Err(MTTError::new(format!("table {} already exists", name))),
None => { None => {
let db = Database::new().await; let table = Table::new().await;
databases.insert(name.to_string(), db); tables.insert(name, table.clone());
Ok(()) Ok(table)
} }
} }
} }
async fn use_database(&self, name: &str) -> Result<Database, DBError> { pub async fn get_table(&self, name: &str) -> Option<Table> {
let databases = self.databases.read().await; let tables = self.tables.read().await;
match databases.get(name) { match tables.get(name) {
Some(db) => Ok(db.clone()), Some(tbl) => Some(tbl.clone()),
None => Err(DBError::new("database name not found")), None => None,
} }
} }
} }
#[derive(Clone)] #[derive(Clone)]
struct Database; pub struct Table;
impl Database { impl Table {
async fn new() -> Self { pub async fn new() -> Self {
Self {} Self {}
} }
async fn add_table(&self, _name: &str) {} async fn new_column(&self, _name: &str, _type: &str) {
}
} }
#[cfg(test)] #[cfg(test)]
mod engine_functions { mod database {
use super::*; use super::*;
#[async_std::test] #[async_std::test]
async fn create_database() { async fn create_table_with_str() {
let mtt = MoreThanText::new().await; let db = MoreThanText::new().await;
mtt.create_database("smith").await.unwrap(); db.new_table("william").await.unwrap();
} }
#[async_std::test] #[async_std::test]
async fn database_names_must_be_unique() -> Result<(), DBError> { async fn create_table_with_string() {
let mtt = MoreThanText::new().await; let db = MoreThanText::new().await;
let msg = "duplicate database name"; db.new_table("marvin".to_string()).await.unwrap();
mtt.create_database("john").await.unwrap(); }
match mtt.create_database("john").await {
Ok(_) => Err(DBError::new("Duplicate names should cause error")), #[async_std::test]
async fn table_names_are_unique() -> Result<(), String> {
let db = MoreThanText::new().await;
let name = "alexandar";
let msg = format!("table {} already exists", name);
db.new_table(name).await.unwrap();
match db.new_table(name).await {
Ok(_) => Err("Duplicate table names are not allowed.".to_string()),
Err(err) => { Err(err) => {
if err.to_string() == msg { if err.to_string() == msg {
Ok(()) Ok(())
} else { } else {
Err(DBError::new(format!( Err(format!(
"incorrect err message: got: '{}' want: '{}'", "Error message is incorrect: Got: '{}' Want: '{}'",
err.to_string(), err.to_string(),
msg msg
))) ))
} }
} }
} }
} }
#[async_std::test] #[async_std::test]
async fn use_database() -> Result<(), DBError> { async fn get_non_existant_table() {
let mtt = MoreThanText::new().await; let db = MoreThanText::new().await;
let dbname = "Johnson"; let table = db.get_table("missing").await;
mtt.create_database(dbname).await.unwrap(); assert!(table.is_none(), "There should be no table.");
mtt.use_database(dbname).await.unwrap();
Ok(())
} }
#[async_std::test] #[async_std::test]
async fn use_missing_database() -> Result<(), DBError> { async fn get_a_table() {
let error = "database name not found"; let db = MoreThanText::new().await;
let mtt = MoreThanText::new().await; let name = "here";
match mtt.use_database("ssmith").await { db.new_table(name).await.unwrap();
Ok(_) => Err(DBError::new("Should raise database missing error")), let table = db.get_table(name).await;
Err(err) => { assert!(table.is_some(), "Table should be found.");
if err.to_string() == error {
Ok(())
} else {
Err(DBError::new(format!(
"Incorrect error message: Got '{}' Want '{}'",
err.to_string(),
error
)))
}
}
}
}
#[async_std::test]
async fn create_get_table() {
let db = "thedatabase";
let mtt = MoreThanText::new().await;
mtt.create_database(db).await.unwrap();
let dbase = mtt.use_database(db).await.unwrap();
dbase.add_table("melvin").await;
} }
} }
#[cfg(test)] #[cfg(test)]
mod database_functions { mod table {
use super::*; use super::*;
#[async_std::test] #[async_std::test]
async fn new_database() { async fn add_column() {
Database::new().await; let tbl = Table::new().await;
} tbl.new_column("fred", "StaticString").await;
#[async_std::test]
async fn new_table() {
let db = Database::new().await;
db.add_table("fred").await;
} }
} }

View File

@ -1,6 +0,0 @@
char = _{ ASCII_ALPHANUMERIC | "_" }
whitespace = _{" " | "\t" | "\r" | "\n"}
name = {char+}
command = {"create database" ~ whitespace+ ~ name ~ ";"}
script = {command+}

View File

@ -1,120 +0,0 @@
pub mod error;
pub mod fieldtype;
use async_std::sync::{Arc, RwLock};
use error::MTTError;
use std::collections::HashMap;
#[derive(Clone)]
pub struct MoreThanText {
tables: Arc<RwLock<HashMap<String, Table>>>,
}
impl MoreThanText {
pub async fn new() -> Self {
Self {
tables: Arc::new(RwLock::new(HashMap::new())),
}
}
pub async fn new_table<S>(&self, tname: S) -> Result<Table, MTTError>
where
S: Into<String>,
{
let mut tables = self.tables.write().await;
let name = tname.into();
match tables.get(&name) {
Some(_) => Err(MTTError::new(format!("table {} already exists", name))),
None => {
let table = Table::new().await;
tables.insert(name, table.clone());
Ok(table)
}
}
}
pub async fn get_table(&self, name: &str) -> Option<Table> {
let tables = self.tables.read().await;
match tables.get(name) {
Some(tbl) => Some(tbl.clone()),
None => None,
}
}
}
#[derive(Clone)]
pub struct Table;
impl Table {
pub async fn new() -> Self {
Self {}
}
async fn new_column(&self, _name: &str, _type: &str) {}
}
#[cfg(test)]
mod database {
use super::*;
#[async_std::test]
async fn create_table_with_str() {
let db = MoreThanText::new().await;
db.new_table("william").await.unwrap();
}
#[async_std::test]
async fn create_table_with_string() {
let db = MoreThanText::new().await;
db.new_table("marvin".to_string()).await.unwrap();
}
#[async_std::test]
async fn table_names_are_unique() -> Result<(), String> {
let db = MoreThanText::new().await;
let name = "alexandar";
let msg = format!("table {} already exists", name);
db.new_table(name).await.unwrap();
match db.new_table(name).await {
Ok(_) => Err("Duplicate table names are not allowed.".to_string()),
Err(err) => {
if err.to_string() == msg {
Ok(())
} else {
Err(format!(
"Error message is incorrect: Got: '{}' Want: '{}'",
err.to_string(),
msg
))
}
}
}
}
#[async_std::test]
async fn get_non_existant_table() {
let db = MoreThanText::new().await;
let table = db.get_table("missing").await;
assert!(table.is_none(), "There should be no table.");
}
#[async_std::test]
async fn get_a_table() {
let db = MoreThanText::new().await;
let name = "here";
db.new_table(name).await.unwrap();
let table = db.get_table(name).await;
assert!(table.is_some(), "Table should be found.");
}
}
#[cfg(test)]
mod table {
use super::*;
#[async_std::test]
async fn add_column() {
let tbl = Table::new().await;
tbl.new_column("fred", "StaticString").await;
}
}