mirror of
https://github.com/Nutomic/ibis.git
synced 2024-12-24 12:11:23 +00:00
partial
This commit is contained in:
parent
10bbc9ed2b
commit
5847e99128
10 changed files with 140 additions and 311 deletions
268
Cargo.lock
generated
268
Cargo.lock
generated
|
@ -20,7 +20,7 @@ dependencies = [
|
||||||
"enum_delegate",
|
"enum_delegate",
|
||||||
"futures",
|
"futures",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"http 1.1.0",
|
"http",
|
||||||
"http-signature-normalization",
|
"http-signature-normalization",
|
||||||
"http-signature-normalization-reqwest",
|
"http-signature-normalization-reqwest",
|
||||||
"httpdate",
|
"httpdate",
|
||||||
|
@ -214,7 +214,7 @@ dependencies = [
|
||||||
"axum-core",
|
"axum-core",
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http 1.1.0",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"hyper",
|
"hyper",
|
||||||
|
@ -248,7 +248,7 @@ dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http 1.1.0",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"mime",
|
"mime",
|
||||||
|
@ -271,7 +271,7 @@ dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"cookie",
|
"cookie",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http 1.1.0",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"mime",
|
"mime",
|
||||||
|
@ -1440,108 +1440,6 @@ dependencies = [
|
||||||
"regex",
|
"regex",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gloo"
|
|
||||||
version = "0.11.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d15282ece24eaf4bd338d73ef580c6714c8615155c4190c781290ee3fa0fd372"
|
|
||||||
dependencies = [
|
|
||||||
"gloo-console",
|
|
||||||
"gloo-dialogs",
|
|
||||||
"gloo-events",
|
|
||||||
"gloo-file",
|
|
||||||
"gloo-history",
|
|
||||||
"gloo-net 0.5.0",
|
|
||||||
"gloo-render",
|
|
||||||
"gloo-storage",
|
|
||||||
"gloo-timers",
|
|
||||||
"gloo-utils",
|
|
||||||
"gloo-worker",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gloo-console"
|
|
||||||
version = "0.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2a17868f56b4a24f677b17c8cb69958385102fa879418052d60b50bc1727e261"
|
|
||||||
dependencies = [
|
|
||||||
"gloo-utils",
|
|
||||||
"js-sys",
|
|
||||||
"serde",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"web-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gloo-dialogs"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bf4748e10122b01435750ff530095b1217cf6546173459448b83913ebe7815df"
|
|
||||||
dependencies = [
|
|
||||||
"wasm-bindgen",
|
|
||||||
"web-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gloo-events"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "27c26fb45f7c385ba980f5fa87ac677e363949e065a083722697ef1b2cc91e41"
|
|
||||||
dependencies = [
|
|
||||||
"wasm-bindgen",
|
|
||||||
"web-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gloo-file"
|
|
||||||
version = "0.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "97563d71863fb2824b2e974e754a81d19c4a7ec47b09ced8a0e6656b6d54bd1f"
|
|
||||||
dependencies = [
|
|
||||||
"gloo-events",
|
|
||||||
"js-sys",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"web-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gloo-history"
|
|
||||||
version = "0.2.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "903f432be5ba34427eac5e16048ef65604a82061fe93789f2212afc73d8617d6"
|
|
||||||
dependencies = [
|
|
||||||
"getrandom",
|
|
||||||
"gloo-events",
|
|
||||||
"gloo-utils",
|
|
||||||
"serde",
|
|
||||||
"serde-wasm-bindgen",
|
|
||||||
"serde_urlencoded",
|
|
||||||
"thiserror 1.0.69",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"web-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gloo-net"
|
|
||||||
version = "0.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "43aaa242d1239a8822c15c645f02166398da4f8b5c4bae795c1f5b44e9eee173"
|
|
||||||
dependencies = [
|
|
||||||
"futures-channel",
|
|
||||||
"futures-core",
|
|
||||||
"futures-sink",
|
|
||||||
"gloo-utils",
|
|
||||||
"http 0.2.12",
|
|
||||||
"js-sys",
|
|
||||||
"pin-project",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"thiserror 1.0.69",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"wasm-bindgen-futures",
|
|
||||||
"web-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gloo-net"
|
name = "gloo-net"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
|
@ -1552,7 +1450,7 @@ dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
"gloo-utils",
|
"gloo-utils",
|
||||||
"http 1.1.0",
|
"http",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"pin-project",
|
"pin-project",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -1563,31 +1461,6 @@ dependencies = [
|
||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gloo-render"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "56008b6744713a8e8d98ac3dcb7d06543d5662358c9c805b4ce2167ad4649833"
|
|
||||||
dependencies = [
|
|
||||||
"wasm-bindgen",
|
|
||||||
"web-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gloo-storage"
|
|
||||||
version = "0.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fbc8031e8c92758af912f9bc08fbbadd3c6f3cfcbf6b64cdf3d6a81f0139277a"
|
|
||||||
dependencies = [
|
|
||||||
"gloo-utils",
|
|
||||||
"js-sys",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"thiserror 1.0.69",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"web-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gloo-timers"
|
name = "gloo-timers"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
@ -1613,37 +1486,6 @@ dependencies = [
|
||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gloo-worker"
|
|
||||||
version = "0.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "085f262d7604911c8150162529cefab3782e91adb20202e8658f7275d2aefe5d"
|
|
||||||
dependencies = [
|
|
||||||
"bincode",
|
|
||||||
"futures",
|
|
||||||
"gloo-utils",
|
|
||||||
"gloo-worker-macros",
|
|
||||||
"js-sys",
|
|
||||||
"pinned",
|
|
||||||
"serde",
|
|
||||||
"thiserror 1.0.69",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"wasm-bindgen-futures",
|
|
||||||
"web-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gloo-worker-macros"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "956caa58d4857bc9941749d55e4bd3000032d8212762586fa5705632967140e7"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro-crate",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.87",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "guardian"
|
name = "guardian"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
@ -1661,7 +1503,7 @@ dependencies = [
|
||||||
"fnv",
|
"fnv",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
"http 1.1.0",
|
"http",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"slab",
|
"slab",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
@ -1721,17 +1563,6 @@ dependencies = [
|
||||||
"utf8-width",
|
"utf8-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "http"
|
|
||||||
version = "0.2.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1"
|
|
||||||
dependencies = [
|
|
||||||
"bytes",
|
|
||||||
"fnv",
|
|
||||||
"itoa",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http"
|
name = "http"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
@ -1750,7 +1581,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
|
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"http 1.1.0",
|
"http",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1761,7 +1592,7 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http 1.1.0",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
@ -1836,7 +1667,7 @@ dependencies = [
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"h2",
|
"h2",
|
||||||
"http 1.1.0",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"httparse",
|
"httparse",
|
||||||
"httpdate",
|
"httpdate",
|
||||||
|
@ -1854,7 +1685,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333"
|
checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http 1.1.0",
|
"http",
|
||||||
"hyper",
|
"hyper",
|
||||||
"hyper-util",
|
"hyper-util",
|
||||||
"rustls",
|
"rustls",
|
||||||
|
@ -1890,7 +1721,7 @@ dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http 1.1.0",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"hyper",
|
"hyper",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
@ -1948,7 +1779,7 @@ dependencies = [
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"futures",
|
"futures",
|
||||||
"getrandom",
|
"getrandom",
|
||||||
"gloo",
|
"gloo-net",
|
||||||
"hex",
|
"hex",
|
||||||
"jsonwebtoken",
|
"jsonwebtoken",
|
||||||
"katex",
|
"katex",
|
||||||
|
@ -1983,6 +1814,7 @@ dependencies = [
|
||||||
"url",
|
"url",
|
||||||
"uuid",
|
"uuid",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2309,7 +2141,7 @@ dependencies = [
|
||||||
"default-struct-builder",
|
"default-struct-builder",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"gloo-timers",
|
"gloo-timers",
|
||||||
"http 1.1.0",
|
"http",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"leptos",
|
"leptos",
|
||||||
|
@ -2455,7 +2287,7 @@ dependencies = [
|
||||||
"any_spawner",
|
"any_spawner",
|
||||||
"either_of",
|
"either_of",
|
||||||
"futures",
|
"futures",
|
||||||
"gloo-net 0.6.0",
|
"gloo-net",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"leptos",
|
"leptos",
|
||||||
"leptos_router_macro",
|
"leptos_router_macro",
|
||||||
|
@ -2782,7 +2614,7 @@ dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"encoding_rs",
|
"encoding_rs",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http 1.1.0",
|
"http",
|
||||||
"httparse",
|
"httparse",
|
||||||
"memchr",
|
"memchr",
|
||||||
"mime",
|
"mime",
|
||||||
|
@ -3123,17 +2955,6 @@ version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pinned"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a829027bd95e54cfe13e3e258a1ae7b645960553fb82b75ff852c29688ee595b"
|
|
||||||
dependencies = [
|
|
||||||
"futures",
|
|
||||||
"rustversion",
|
|
||||||
"thiserror 1.0.69",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pkcs1"
|
name = "pkcs1"
|
||||||
version = "0.7.5"
|
version = "0.7.5"
|
||||||
|
@ -3218,16 +3039,6 @@ dependencies = [
|
||||||
"syn 2.0.87",
|
"syn 2.0.87",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[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 0.19.15",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-error"
|
name = "proc-macro-error"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
|
@ -3611,7 +3422,7 @@ dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"h2",
|
"h2",
|
||||||
"http 1.1.0",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"hyper",
|
"hyper",
|
||||||
|
@ -3657,7 +3468,7 @@ checksum = "562ceb5a604d3f7c885a792d42c199fd8af239d0a51b2fa6a78aafa092452b04"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"http 1.1.0",
|
"http",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror 1.0.69",
|
"thiserror 1.0.69",
|
||||||
|
@ -3917,17 +3728,6 @@ dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde-wasm-bindgen"
|
|
||||||
version = "0.6.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b"
|
|
||||||
dependencies = [
|
|
||||||
"js-sys",
|
|
||||||
"serde",
|
|
||||||
"wasm-bindgen",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.215"
|
version = "1.0.215"
|
||||||
|
@ -4005,8 +3805,8 @@ dependencies = [
|
||||||
"const_format",
|
"const_format",
|
||||||
"dashmap",
|
"dashmap",
|
||||||
"futures",
|
"futures",
|
||||||
"gloo-net 0.6.0",
|
"gloo-net",
|
||||||
"http 1.1.0",
|
"http",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"hyper",
|
"hyper",
|
||||||
"inventory",
|
"inventory",
|
||||||
|
@ -4540,7 +4340,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_spanned",
|
"serde_spanned",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
"toml_edit 0.22.22",
|
"toml_edit",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -4552,17 +4352,6 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "toml_edit"
|
|
||||||
version = "0.19.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
|
|
||||||
dependencies = [
|
|
||||||
"indexmap",
|
|
||||||
"toml_datetime",
|
|
||||||
"winnow 0.5.40",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_edit"
|
name = "toml_edit"
|
||||||
version = "0.22.22"
|
version = "0.22.22"
|
||||||
|
@ -4573,7 +4362,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_spanned",
|
"serde_spanned",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
"winnow 0.6.20",
|
"winnow",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -4616,7 +4405,7 @@ dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http 1.1.0",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"http-range-header",
|
"http-range-header",
|
||||||
|
@ -4641,7 +4430,7 @@ dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http 1.1.0",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"http-range-header",
|
"http-range-header",
|
||||||
|
@ -5152,15 +4941,6 @@ version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winnow"
|
|
||||||
version = "0.5.40"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winnow"
|
name = "winnow"
|
||||||
version = "0.6.20"
|
version = "0.6.20"
|
||||||
|
|
|
@ -121,7 +121,8 @@ tower = { version = "0.5.1", optional = true }
|
||||||
tower-layer = { version = "0.3.3", optional = true }
|
tower-layer = { version = "0.3.3", optional = true }
|
||||||
console_log = "1.0.0"
|
console_log = "1.0.0"
|
||||||
send_wrapper = "0.6.0"
|
send_wrapper = "0.6.0"
|
||||||
gloo = "0.11.0"
|
gloo-net = "0.6.0"
|
||||||
|
web-sys = "0.3.72"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pretty_assertions = "1.4.1"
|
pretty_assertions = "1.4.1"
|
||||||
|
|
|
@ -7,16 +7,10 @@ use crate::{
|
||||||
utils::generate_activity_id,
|
utils::generate_activity_id,
|
||||||
},
|
},
|
||||||
common::{
|
common::{
|
||||||
utils::http_protocol_str,
|
utils::http_protocol_str, Auth, DbArticle, DbInstance, DbPerson, EditVersion, AUTH_COOKIE,
|
||||||
Auth,
|
|
||||||
DbArticle,
|
|
||||||
DbInstance,
|
|
||||||
DbPerson,
|
|
||||||
EditVersion,
|
|
||||||
AUTH_COOKIE,
|
|
||||||
MAIN_PAGE_NAME,
|
MAIN_PAGE_NAME,
|
||||||
},
|
},
|
||||||
frontend::app::App,
|
frontend::app::{shell, App},
|
||||||
};
|
};
|
||||||
use activitypub_federation::{
|
use activitypub_federation::{
|
||||||
config::{Data, FederationConfig, FederationMiddleware},
|
config::{Data, FederationConfig, FederationMiddleware},
|
||||||
|
@ -27,12 +21,12 @@ use api::api_routes;
|
||||||
use assets::file_and_error_handler;
|
use assets::file_and_error_handler;
|
||||||
use axum::{
|
use axum::{
|
||||||
body::Body,
|
body::Body,
|
||||||
|
extract::State,
|
||||||
http::{HeaderValue, Request},
|
http::{HeaderValue, Request},
|
||||||
middleware::Next,
|
middleware::Next,
|
||||||
response::{IntoResponse, Response},
|
response::{IntoResponse, Response},
|
||||||
routing::get,
|
routing::get,
|
||||||
Router,
|
Router, ServiceExt,
|
||||||
ServiceExt,
|
|
||||||
};
|
};
|
||||||
use axum_extra::extract::CookieJar;
|
use axum_extra::extract::CookieJar;
|
||||||
use axum_macros::debug_middleware;
|
use axum_macros::debug_middleware;
|
||||||
|
@ -43,8 +37,7 @@ use diesel::{
|
||||||
};
|
};
|
||||||
use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};
|
use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};
|
||||||
use federation::objects::{
|
use federation::objects::{
|
||||||
articles_collection::local_articles_url,
|
articles_collection::local_articles_url, instance_collection::linked_instances_url,
|
||||||
instance_collection::linked_instances_url,
|
|
||||||
};
|
};
|
||||||
use leptos::prelude::*;
|
use leptos::prelude::*;
|
||||||
use leptos_axum::{generate_route_list, LeptosRoutes};
|
use leptos_axum::{generate_route_list, LeptosRoutes};
|
||||||
|
@ -123,13 +116,17 @@ pub async fn start(config: IbisConfig, override_hostname: Option<SocketAddr>) ->
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make auth token available in hydrate mode
|
/// Make auth token available in hydrate mode
|
||||||
async fn leptos_routes_handler(jar: CookieJar, req: Request<Body>) -> Response {
|
async fn leptos_routes_handler(
|
||||||
|
jar: CookieJar,
|
||||||
|
State(leptos_options): State<LeptosOptions>,
|
||||||
|
req: Request<Body>,
|
||||||
|
) -> Response {
|
||||||
let handler = leptos_axum::render_app_async_with_context(
|
let handler = leptos_axum::render_app_async_with_context(
|
||||||
move || {
|
move || {
|
||||||
let cookie = jar.get(AUTH_COOKIE).map(|c| c.value().to_string());
|
let cookie = jar.get(AUTH_COOKIE).map(|c| c.value().to_string());
|
||||||
provide_context(Auth(cookie));
|
provide_context(Auth(cookie));
|
||||||
},
|
},
|
||||||
move || view! { <App /> },
|
move || shell(leptos_options.clone()),
|
||||||
);
|
);
|
||||||
|
|
||||||
handler(req).await.into_response()
|
handler(req).await.into_response()
|
||||||
|
|
|
@ -62,7 +62,7 @@ impl ApiClient {
|
||||||
if let Some(query) = query {
|
if let Some(query) = query {
|
||||||
req = req.query(&query);
|
req = req.query(&query);
|
||||||
}
|
}
|
||||||
send::<T>(req).await
|
self.send::<T>(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_article(&self, data: GetArticleForm) -> MyResult<ArticleView> {
|
pub async fn get_article(&self, data: GetArticleForm) -> MyResult<ArticleView> {
|
||||||
|
@ -78,7 +78,7 @@ impl ApiClient {
|
||||||
.client
|
.client
|
||||||
.post(self.request_endpoint("/api/v1/account/register"))
|
.post(self.request_endpoint("/api/v1/account/register"))
|
||||||
.form(®ister_form);
|
.form(®ister_form);
|
||||||
send::<LocalUserView>(req).await
|
self.send::<LocalUserView>(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn login(&self, login_form: LoginUserForm) -> MyResult<LocalUserView> {
|
pub async fn login(&self, login_form: LoginUserForm) -> MyResult<LocalUserView> {
|
||||||
|
@ -86,7 +86,7 @@ impl ApiClient {
|
||||||
.client
|
.client
|
||||||
.post(self.request_endpoint("/api/v1/account/login"))
|
.post(self.request_endpoint("/api/v1/account/login"))
|
||||||
.form(&login_form);
|
.form(&login_form);
|
||||||
send::<LocalUserView>(req).await
|
self.send::<LocalUserView>(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_article(&self, data: &CreateArticleForm) -> MyResult<ArticleView> {
|
pub async fn create_article(&self, data: &CreateArticleForm) -> MyResult<ArticleView> {
|
||||||
|
@ -94,7 +94,7 @@ impl ApiClient {
|
||||||
.client
|
.client
|
||||||
.post(self.request_endpoint("/api/v1/article"))
|
.post(self.request_endpoint("/api/v1/article"))
|
||||||
.form(data);
|
.form(data);
|
||||||
send(req).await
|
self.send(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn edit_article_with_conflict(
|
pub async fn edit_article_with_conflict(
|
||||||
|
@ -105,7 +105,7 @@ impl ApiClient {
|
||||||
.client
|
.client
|
||||||
.patch(self.request_endpoint("/api/v1/article"))
|
.patch(self.request_endpoint("/api/v1/article"))
|
||||||
.form(edit_form);
|
.form(edit_form);
|
||||||
send(req).await
|
self.send(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn edit_article(&self, edit_form: &EditArticleForm) -> MyResult<ArticleView> {
|
pub async fn edit_article(&self, edit_form: &EditArticleForm) -> MyResult<ArticleView> {
|
||||||
|
@ -124,14 +124,14 @@ impl ApiClient {
|
||||||
let req = self
|
let req = self
|
||||||
.client
|
.client
|
||||||
.get(self.request_endpoint("/api/v1/user/notifications/list"));
|
.get(self.request_endpoint("/api/v1/user/notifications/list"));
|
||||||
send(req).await
|
self.send(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn notifications_count(&self) -> MyResult<usize> {
|
pub async fn notifications_count(&self) -> MyResult<usize> {
|
||||||
let req = self
|
let req = self
|
||||||
.client
|
.client
|
||||||
.get(self.request_endpoint("/api/v1/user/notifications/count"));
|
.get(self.request_endpoint("/api/v1/user/notifications/count"));
|
||||||
send(req).await
|
self.send(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn approve_article(&self, article_id: ArticleId, approve: bool) -> MyResult<()> {
|
pub async fn approve_article(&self, article_id: ArticleId, approve: bool) -> MyResult<()> {
|
||||||
|
@ -143,7 +143,7 @@ impl ApiClient {
|
||||||
.client
|
.client
|
||||||
.post(self.request_endpoint("/api/v1/article/approve"))
|
.post(self.request_endpoint("/api/v1/article/approve"))
|
||||||
.form(&form);
|
.form(&form);
|
||||||
send(req).await
|
self.send(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_conflict(&self, conflict_id: ConflictId) -> MyResult<()> {
|
pub async fn delete_conflict(&self, conflict_id: ConflictId) -> MyResult<()> {
|
||||||
|
@ -152,7 +152,7 @@ impl ApiClient {
|
||||||
.client
|
.client
|
||||||
.delete(self.request_endpoint("/api/v1/conflict"))
|
.delete(self.request_endpoint("/api/v1/conflict"))
|
||||||
.form(&form);
|
.form(&form);
|
||||||
send(req).await
|
self.send(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn search(&self, search_form: &SearchArticleForm) -> MyResult<Vec<DbArticle>> {
|
pub async fn search(&self, search_form: &SearchArticleForm) -> MyResult<Vec<DbArticle>> {
|
||||||
|
@ -192,6 +192,8 @@ impl ApiClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn follow_instance(&self, follow_form: FollowInstance) -> MyResult<()> {
|
pub async fn follow_instance(&self, follow_form: FollowInstance) -> MyResult<()> {
|
||||||
|
todo!();
|
||||||
|
/*
|
||||||
// cant use post helper because follow doesnt return json
|
// cant use post helper because follow doesnt return json
|
||||||
let res = self
|
let res = self
|
||||||
.client
|
.client
|
||||||
|
@ -204,19 +206,19 @@ impl ApiClient {
|
||||||
} else {
|
} else {
|
||||||
Err(anyhow!("API error: {}", res.text().await?).into())
|
Err(anyhow!("API error: {}", res.text().await?).into())
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn site(&self) -> MyResult<SiteView> {
|
pub async fn site(&self) -> MyResult<SiteView> {
|
||||||
let req = self.client.get(self.request_endpoint("/api/v1/site"));
|
let req = self.client.get(self.request_endpoint("/api/v1/site"));
|
||||||
send(req).await
|
self.send(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn logout(&self) -> MyResult<()> {
|
pub async fn logout(&self) -> MyResult<()> {
|
||||||
self.client
|
let req = self
|
||||||
.get(self.request_endpoint("/api/v1/account/logout"))
|
.client
|
||||||
.send()
|
.get(self.request_endpoint("/api/v1/account/logout"));
|
||||||
.await?;
|
Ok(self.send(req).await.unwrap())
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn fork_article(&self, form: &ForkArticleForm) -> MyResult<ArticleView> {
|
pub async fn fork_article(&self, form: &ForkArticleForm) -> MyResult<ArticleView> {
|
||||||
|
@ -224,7 +226,7 @@ impl ApiClient {
|
||||||
.client
|
.client
|
||||||
.post(self.request_endpoint("/api/v1/article/fork"))
|
.post(self.request_endpoint("/api/v1/article/fork"))
|
||||||
.form(form);
|
.form(form);
|
||||||
Ok(send(req).await.unwrap())
|
Ok(self.send(req).await.unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn protect_article(&self, params: &ProtectArticleForm) -> MyResult<DbArticle> {
|
pub async fn protect_article(&self, params: &ProtectArticleForm) -> MyResult<DbArticle> {
|
||||||
|
@ -232,7 +234,7 @@ impl ApiClient {
|
||||||
.client
|
.client
|
||||||
.post(self.request_endpoint("/api/v1/article/protect"))
|
.post(self.request_endpoint("/api/v1/article/protect"))
|
||||||
.form(params);
|
.form(params);
|
||||||
send(req).await
|
self.send(req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn resolve_article(&self, id: Url) -> MyResult<ArticleView> {
|
pub async fn resolve_article(&self, id: Url) -> MyResult<ArticleView> {
|
||||||
|
@ -249,23 +251,10 @@ impl ApiClient {
|
||||||
pub async fn get_user(&self, data: GetUserForm) -> MyResult<DbPerson> {
|
pub async fn get_user(&self, data: GetUserForm) -> MyResult<DbPerson> {
|
||||||
self.get("/api/v1/user", Some(data)).await
|
self.get("/api/v1/user", Some(data)).await
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "ssr")]
|
||||||
fn request_endpoint(&self, path: &str) -> String {
|
async fn send<T>(&self, mut req: RequestBuilder) -> MyResult<T>
|
||||||
let protocol = if self.ssl { "https" } else { "http" };
|
|
||||||
format!("{protocol}://{}{path}", &self.hostname)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn send<T>(#[allow(unused_mut)] mut req: RequestBuilder) -> MyResult<T>
|
|
||||||
where
|
where
|
||||||
T: for<'de> Deserialize<'de>,
|
T: for<'de> Deserialize<'de>,
|
||||||
{
|
|
||||||
#[cfg(not(feature = "ssr"))]
|
|
||||||
{
|
|
||||||
req = req.fetch_credentials_include();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "ssr")]
|
|
||||||
{
|
{
|
||||||
use crate::common::{Auth, AUTH_COOKIE};
|
use crate::common::{Auth, AUTH_COOKIE};
|
||||||
use leptos::prelude::use_context;
|
use leptos::prelude::use_context;
|
||||||
|
@ -275,7 +264,6 @@ where
|
||||||
if let Some(Auth(Some(auth))) = auth {
|
if let Some(Auth(Some(auth))) = auth {
|
||||||
req = req.header(HeaderName::from_static(AUTH_COOKIE), auth);
|
req = req.header(HeaderName::from_static(AUTH_COOKIE), auth);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
let res = req.send().await?;
|
let res = req.send().await?;
|
||||||
let status = res.status();
|
let status = res.status();
|
||||||
let text = res.text().await?;
|
let text = res.text().await?;
|
||||||
|
@ -285,3 +273,53 @@ where
|
||||||
Err(anyhow!("API error: {text}").into())
|
Err(anyhow!("API error: {text}").into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "hydrate")]
|
||||||
|
fn send<T>(
|
||||||
|
&self,
|
||||||
|
mut req: RequestBuilder,
|
||||||
|
) -> impl std::future::Future<Output = MyResult<T>> + Send
|
||||||
|
where
|
||||||
|
T: for<'de> Deserialize<'de>,
|
||||||
|
{
|
||||||
|
use gloo_net::http::*;
|
||||||
|
use leptos::prelude::on_cleanup;
|
||||||
|
use send_wrapper::SendWrapper;
|
||||||
|
use web_sys::RequestCredentials;
|
||||||
|
|
||||||
|
SendWrapper::new(async move {
|
||||||
|
let abort_controller = SendWrapper::new(web_sys::AbortController::new().ok());
|
||||||
|
let abort_signal = abort_controller.as_ref().map(|a| a.signal());
|
||||||
|
|
||||||
|
// abort in-flight requests if, e.g., we've navigated away from this page
|
||||||
|
on_cleanup(move || {
|
||||||
|
if let Some(abort_controller) = abort_controller.take() {
|
||||||
|
abort_controller.abort()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
if status == StatusCode::OK {
|
||||||
|
Ok(serde_json::from_str(&text).map_err(|e| anyhow!("Json error on {text}: {e}"))?)
|
||||||
|
} else {
|
||||||
|
Err(anyhow!("API error: {text}").into())
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
Ok(RequestBuilder::new("/api/v1/site")
|
||||||
|
.method(Method::GET)
|
||||||
|
.abort_signal(abort_signal.as_ref())
|
||||||
|
.credentials(RequestCredentials::Include)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.json()
|
||||||
|
.await
|
||||||
|
.unwrap())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn request_endpoint(&self, path: &str) -> String {
|
||||||
|
let protocol = if self.ssl { "https" } else { "http" };
|
||||||
|
format!("{protocol}://{}{path}", &self.hostname)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -6,12 +6,8 @@ use crate::{
|
||||||
dark_mode::DarkMode,
|
dark_mode::DarkMode,
|
||||||
pages::{
|
pages::{
|
||||||
article::{
|
article::{
|
||||||
actions::ArticleActions,
|
actions::ArticleActions, create::CreateArticle, edit::EditArticle,
|
||||||
create::CreateArticle,
|
history::ArticleHistory, list::ListArticles, read::ReadArticle,
|
||||||
edit::EditArticle,
|
|
||||||
history::ArticleHistory,
|
|
||||||
list::ListArticles,
|
|
||||||
read::ReadArticle,
|
|
||||||
},
|
},
|
||||||
diff::EditDiff,
|
diff::EditDiff,
|
||||||
instance::{details::InstanceDetails, list::ListInstances},
|
instance::{details::InstanceDetails, list::ListInstances},
|
||||||
|
@ -59,6 +55,23 @@ impl<T: Default + Send + Sync> DefaultResource<T> for Resource<T> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn shell(options: LeptosOptions) -> impl IntoView {
|
||||||
|
view! {
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<AutoReload options=options.clone() />
|
||||||
|
<HydrationScripts options />
|
||||||
|
<MetaTags />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<App />
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn App() -> impl IntoView {
|
pub fn App() -> impl IntoView {
|
||||||
|
|
|
@ -35,7 +35,7 @@ pub fn ArticleNav(article: Resource<ArticleView>, active_tab: ActiveTab) -> impl
|
||||||
let form = GetInstance {
|
let form = GetInstance {
|
||||||
id: Some(instance_id),
|
id: Some(instance_id),
|
||||||
};
|
};
|
||||||
CLIENT.get_instance(form).await.unwrap()
|
CLIENT.get_instance(&form).await.unwrap()
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
let article_link = article_link(&article_.article);
|
let article_link = article_link(&article_.article);
|
||||||
|
|
|
@ -25,7 +25,7 @@ pub fn ArticleActions() -> impl IntoView {
|
||||||
};
|
};
|
||||||
async move {
|
async move {
|
||||||
set_error.update(|e| *e = None);
|
set_error.update(|e| *e = None);
|
||||||
let result = CLIENT.fork_article(params).await;
|
let result = CLIENT.fork_article(¶ms).await;
|
||||||
match result {
|
match result {
|
||||||
Ok(res) => set_fork_response.set(Some(res.article)),
|
Ok(res) => set_fork_response.set(Some(res.article)),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
@ -41,7 +41,7 @@ pub fn ArticleActions() -> impl IntoView {
|
||||||
};
|
};
|
||||||
async move {
|
async move {
|
||||||
set_error.update(|e| *e = None);
|
set_error.update(|e| *e = None);
|
||||||
let result = CLIENT.protect_article(params).await;
|
let result = CLIENT.protect_article(¶ms).await;
|
||||||
match result {
|
match result {
|
||||||
Ok(_res) => article.refetch(),
|
Ok(_res) => article.refetch(),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
|
|
@ -32,7 +32,7 @@ pub fn CreateArticle() -> impl IntoView {
|
||||||
summary,
|
summary,
|
||||||
};
|
};
|
||||||
set_wait_for_response.update(|w| *w = true);
|
set_wait_for_response.update(|w| *w = true);
|
||||||
let res = CLIENT.create_article(form).await;
|
let res = CLIENT.create_article(&form).await;
|
||||||
set_wait_for_response.update(|w| *w = false);
|
set_wait_for_response.update(|w| *w = false);
|
||||||
match res {
|
match res {
|
||||||
Ok(_res) => {
|
Ok(_res) => {
|
||||||
|
|
|
@ -89,7 +89,7 @@ pub fn EditArticle() -> impl IntoView {
|
||||||
resolve_conflict_id,
|
resolve_conflict_id,
|
||||||
};
|
};
|
||||||
set_wait_for_response.update(|w| *w = true);
|
set_wait_for_response.update(|w| *w = true);
|
||||||
let res = CLIENT.edit_article_with_conflict(form).await;
|
let res = CLIENT.edit_article_with_conflict(&form).await;
|
||||||
set_wait_for_response.update(|w| *w = false);
|
set_wait_for_response.update(|w| *w = false);
|
||||||
match res {
|
match res {
|
||||||
Ok(Some(conflict)) => {
|
Ok(Some(conflict)) => {
|
||||||
|
|
|
@ -29,7 +29,7 @@ pub fn Search() -> impl IntoView {
|
||||||
let mut search_results = SearchResults::default();
|
let mut search_results = SearchResults::default();
|
||||||
let url = Url::parse(&query);
|
let url = Url::parse(&query);
|
||||||
let search_data = SearchArticleForm { query };
|
let search_data = SearchArticleForm { query };
|
||||||
let search = CLIENT.search(search_data);
|
let search = CLIENT.search(&search_data);
|
||||||
|
|
||||||
match search.await {
|
match search.await {
|
||||||
Ok(mut a) => search_results.articles.append(&mut a),
|
Ok(mut a) => search_results.articles.append(&mut a),
|
||||||
|
|
Loading…
Reference in a new issue