initial commit
This commit is contained in:
commit
b9de50bb2b
|
@ -0,0 +1,2 @@
|
|||
/target
|
||||
**/*.rs.bk
|
|
@ -0,0 +1,607 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "anymap"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace-sys"
|
||||
version = "0.1.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base-x"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "boolinator"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "discard"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "failure"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "failure_derive"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "galmon-web"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_repr 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"stdweb 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"yew 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "iovec"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.62"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-nested"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.4.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.6.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_repr"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "stdweb"
|
||||
version = "0.4.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"discard 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"stdweb-derive 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"stdweb-internal-macros 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"stdweb-internal-runtime 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasm-bindgen 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stdweb-derive"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stdweb-internal-macros"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"base-x 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stdweb-internal-runtime"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.15.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "synstructure"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"wasm-bindgen-macro 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasm-bindgen-shared 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasm-bindgen-macro-support 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasm-bindgen-backend 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasm-bindgen-shared 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "yew"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"anymap 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bincode 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"indexmap 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"stdweb 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasm-bindgen 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"yew-macro 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yew-macro"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"boolinator 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[metadata]
|
||||
"checksum anymap 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "33954243bd79057c2de7338850b85983a44588021f8a5fee574a8888c6de4344"
|
||||
"checksum autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875"
|
||||
"checksum backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)" = "690a62be8920ccf773ee00ef0968649b0e724cda8bd5b12286302b4ae955fdf5"
|
||||
"checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b"
|
||||
"checksum base-x 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "76f4eae81729e69bb1819a26c6caac956cc429238388091f98cb6cd858f16443"
|
||||
"checksum bincode 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f2fb9e29e72fd6bc12071533d5dc7664cb01480c59406f656d7ac25c7bd8ff7"
|
||||
"checksum boolinator 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cfa8873f51c92e232f9bac4065cddef41b714152812bfc5f7672ba16d6ef8cd9"
|
||||
"checksum bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad807f2fc2bf185eeb98ff3a901bd46dc5ad58163d0fa4577ba0d25674d71708"
|
||||
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
|
||||
"checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"
|
||||
"checksum cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "4fc9a35e1f4290eb9e5fc54ba6cf40671ed2a2514c3eeb2b2a908dda2ea5a1be"
|
||||
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
"checksum chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e8493056968583b0193c1bb04d6f7684586f3726992d6c573261941a895dbd68"
|
||||
"checksum discard 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
|
||||
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
|
||||
"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
|
||||
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
|
||||
"checksum http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "372bcb56f939e449117fb0869c2e8fd8753a8223d92a172c6e808cf123a5b6e4"
|
||||
"checksum indexmap 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a61202fbe46c4a951e9404a720a0180bcf3212c750d735cb5c4ba4dc551299f3"
|
||||
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
|
||||
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
|
||||
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
|
||||
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||
"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
|
||||
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
|
||||
"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||
"checksum proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e688f31d92ffd7c1ddc57a1b4e6d773c0f2a14ee437a4b0a4f5a69c80eb221c8"
|
||||
"checksum proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e"
|
||||
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||
"checksum proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afdc77cc74ec70ed262262942ebb7dac3d479e9e5cfa2da1841c0806f6cdabcc"
|
||||
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
||||
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
|
||||
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
|
||||
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
|
||||
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997"
|
||||
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
"checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd"
|
||||
"checksum serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e"
|
||||
"checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704"
|
||||
"checksum serde_repr 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "cd02c7587ec314570041b2754829f84d873ced14a96d1fd1823531e11db40573"
|
||||
"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
|
||||
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
||||
"checksum stdweb 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)" = "a68c0ce28cf7400ed022e18da3c4591e14e1df02c70e93573cc59921b3923aeb"
|
||||
"checksum stdweb-derive 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0e21ebd9179de08f2300a65454268a17ea3de204627458588c84319c4def3930"
|
||||
"checksum stdweb-internal-macros 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e68f7d08b76979a43e93fe043b66d2626e35d41d68b0b85519202c6dd8ac59fa"
|
||||
"checksum stdweb-internal-runtime 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d52317523542cc0af5b7e31017ad0f7d1e78da50455e38d5657cd17754f617da"
|
||||
"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
|
||||
"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf"
|
||||
"checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f"
|
||||
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
|
||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
||||
"checksum wasm-bindgen 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "ffde3534e5fa6fd936e3260cd62cd644b8656320e369388f9303c955895e35d4"
|
||||
"checksum wasm-bindgen-backend 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "40c0543374a7ae881cdc5d32d19de28d1d1929e92263ffa7e31712cc2d53f9f1"
|
||||
"checksum wasm-bindgen-macro 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "f914c94c2c5f4c9364510ca2429e59c92157ec89429243bcc245e983db990a71"
|
||||
"checksum wasm-bindgen-macro-support 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "9168c413491e4233db7b6884f09a43beb00c14d11d947ffd165242daa48a2385"
|
||||
"checksum wasm-bindgen-shared 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "326c32126e1a157b6ced7400061a84ac5b11182b2cda6edad7314eb3ae9ac9fe"
|
||||
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
"checksum yew 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "479f32df0b06ef05893cbb3c195a0ae92b10587e2eff1969f1a7741d3fb96666"
|
||||
"checksum yew-macro 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92d6380df5f9c5d4cfd1191bd31ed44299f302e6040126d602ee8b262252cb7e"
|
|
@ -0,0 +1,14 @@
|
|||
[package]
|
||||
name = "galmon-web"
|
||||
version = "0.1.0"
|
||||
authors = ["Stefan Bühler <stbuehler@web.de>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
chrono = { version = "0.4.9", features = ["serde"] }
|
||||
failure = "0.1.5"
|
||||
percent-encoding = "2.1.0"
|
||||
serde = { version = "1.0.99", features = ["rc"] }
|
||||
serde_repr = "0.1.5"
|
||||
stdweb = "0.4.18"
|
||||
yew = "0.8.0"
|
|
@ -0,0 +1,3 @@
|
|||
Experimental, alternative frontend (written in rust) for https://galmon.eu
|
||||
|
||||
Code and algorithms for map rendering heavily inspired (read "copied") from [d3-geo](https://github.com/d3/d3-geo).
|
|
@ -0,0 +1,106 @@
|
|||
// build adapter with custom serialization names / grouping of (flattened) optional entries
|
||||
macro_rules! adapter {
|
||||
(
|
||||
$adapter:ident => Option<$base:ident> {
|
||||
$(
|
||||
$(#[$field_meta:meta])*
|
||||
$field:ident: $field_ty:ty,
|
||||
)*
|
||||
}
|
||||
) => {
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct $adapter {
|
||||
$(
|
||||
$(#[$field_meta])*
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
$field: Option<$field_ty>,
|
||||
)*
|
||||
}
|
||||
|
||||
impl $adapter {
|
||||
pub fn serialize<S>(value: &Option<$base>, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
Self::from(value.clone()).serialize(serializer)
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<$base>, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
<$adapter as serde::Deserialize>::deserialize(deserializer).map(Option::<$base>::from)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Option<$base>> for $adapter {
|
||||
fn from(base: Option<$base>) -> Self {
|
||||
if let Some(base) = base {
|
||||
Self {
|
||||
$($field: Some(base.$field),)*
|
||||
}
|
||||
} else {
|
||||
Self {
|
||||
$($field: None,)*
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<$adapter> for Option<$base> {
|
||||
fn from(adapter: $adapter) -> Self {
|
||||
Option::Some($base {
|
||||
$($field: adapter.$field?,)*
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
(
|
||||
$adapter:ident => $base:ident {
|
||||
$(
|
||||
$(#[$field_meta:meta])*
|
||||
$field:ident: $field_ty:ty,
|
||||
)*
|
||||
}
|
||||
) => {
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct $adapter {
|
||||
$(
|
||||
$(#[$field_meta])*
|
||||
$field: $field_ty,
|
||||
)*
|
||||
}
|
||||
|
||||
impl $adapter {
|
||||
pub fn serialize<S>(value: &$base, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
Self::from(value.clone()).serialize(serializer)
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<$base, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
<$adapter as serde::Deserialize>::deserialize(deserializer).map($base::from)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<$base> for $adapter {
|
||||
fn from(base: $base) -> Self {
|
||||
Self {
|
||||
$($field: base.$field,)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<$adapter> for $base {
|
||||
fn from(adapter: $adapter) -> Self {
|
||||
Self {
|
||||
$($field: adapter.$field,)*
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
use failure::{format_err, Error, ResultExt};
|
||||
use serde::Deserialize;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::fmt;
|
||||
use yew::prelude::*;
|
||||
use yew::{
|
||||
format::{Json, Nothing, Text},
|
||||
services::fetch::{Request, Response, FetchService, FetchTask as YewFetchTask},
|
||||
};
|
||||
use crate::config::Config;
|
||||
|
||||
pub struct FetchTask {
|
||||
_task: YewFetchTask,
|
||||
}
|
||||
|
||||
impl FetchTask {
|
||||
fn new(task: YewFetchTask) -> Self {
|
||||
Self { _task: task }
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for FetchTask {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.write_str("FetchTask")
|
||||
}
|
||||
}
|
||||
|
||||
pub struct APIService<Message: 'static> {
|
||||
send_message: Callback<Message>,
|
||||
fetch_service: RefCell<FetchService>,
|
||||
}
|
||||
|
||||
impl APIService<()> {
|
||||
pub fn new_no_message() -> Self {
|
||||
Self::new(Callback::from(|()| ()))
|
||||
}
|
||||
}
|
||||
|
||||
impl<Message: 'static> APIService<Message> {
|
||||
pub fn new(send_message: Callback<Message>) -> Self
|
||||
{
|
||||
Self {
|
||||
send_message,
|
||||
fetch_service: RefCell::new(FetchService::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fetch<T, F, IN>(&self, req: Request<IN>, callback: F) -> Option<FetchTask>
|
||||
where
|
||||
T: for<'de> Deserialize<'de>,
|
||||
F: FnOnce(Result<T, Error>) -> Message + 'static,
|
||||
IN: Into<Text>,
|
||||
{
|
||||
let method = req.method().clone();
|
||||
let url = req.uri().clone();
|
||||
let callback = Cell::new(Some(callback));
|
||||
let send_message = self.send_message.clone();
|
||||
let decode_response = move |response: Response<Text>| {
|
||||
// only works once
|
||||
let callback = callback.replace(None).unwrap();
|
||||
|
||||
let (parts, body) = response.into_parts();
|
||||
if !parts.status.is_success() {
|
||||
if parts.headers.is_empty() {
|
||||
// CORS failure
|
||||
jslog!("{} {:?} failed due to CORS, can't see real error (status: {})", method, url, parts.status);
|
||||
return send_message.emit(callback(Err(format_err!("{} {:?} failed due to CORS", method, url))));
|
||||
}
|
||||
let e = format!("{} {:?} failed with {}", method, url, parts.status);
|
||||
crate::log(&e);
|
||||
return send_message.emit(callback(Err(failure::err_msg(e))));
|
||||
}
|
||||
|
||||
let body = match body {
|
||||
Err(e) => {
|
||||
let e = format!("{} {:?} failed request body although status {} is fine: {}", method, url, parts.status, e);
|
||||
crate::log(&e);
|
||||
return send_message.emit(callback(Err(failure::err_msg(e))));
|
||||
},
|
||||
Ok(v) => v
|
||||
};
|
||||
send_message.emit(callback(Json::<Result<T, Error>>::from(Ok(body)).0.with_context(|e| format!("parsing response failed: {}", e)).map_err(Error::from)));
|
||||
};
|
||||
let mut service = self.fetch_service.borrow_mut();
|
||||
Some(FetchTask::new(service.fetch(req, Callback::<Response<Text>>::from(decode_response))))
|
||||
}
|
||||
|
||||
pub fn get<T, F>(&self, url: &str, callback: F) -> Option<FetchTask>
|
||||
where
|
||||
T: for<'de> Deserialize<'de>,
|
||||
F: FnOnce(Result<T, Error>) -> Message + 'static,
|
||||
{
|
||||
self.fetch(Request::get(url).body(Nothing).unwrap(), callback)
|
||||
}
|
||||
|
||||
pub fn api_get<T, F>(&self, config: &Config, path: fmt::Arguments<'_>, callback: F) -> Option<FetchTask>
|
||||
where
|
||||
T: for<'de> Deserialize<'de>,
|
||||
F: FnOnce(Result<T, Error>) -> Message + 'static,
|
||||
{
|
||||
let url = format!("{}{}", config.base_url, path);
|
||||
let req = Request::get(url).body(Nothing).unwrap();
|
||||
self.fetch(req, callback)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Message> fmt::Debug for APIService<Message> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.write_str("APIService")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,375 @@
|
|||
use failure::Error;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use std::collections::HashMap;
|
||||
use std::time::SystemTime;
|
||||
|
||||
#[macro_use]
|
||||
mod adapter_macro;
|
||||
mod apiservice;
|
||||
pub mod world_geo;
|
||||
|
||||
pub use self::apiservice::{APIService, FetchTask};
|
||||
|
||||
use crate::config::Config;
|
||||
|
||||
impl<Message: 'static> APIService<Message> {
|
||||
pub fn api_world_geo<F>(&self, config: &Config, callback: F) -> Option<FetchTask>
|
||||
where
|
||||
F: FnOnce(Result<world_geo::FeatureCollection, Error>) -> Message + 'static,
|
||||
{
|
||||
self.api_get(config, format_args!("/geo/world.geojson"), callback)
|
||||
}
|
||||
}
|
||||
|
||||
pub type DateTime = chrono::DateTime<chrono::Utc>;
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Global {
|
||||
#[serde(rename = "gps-offset-ns")]
|
||||
pub gps_offset_ns: f64,
|
||||
#[serde(rename = "gps-utc-offset-ns")]
|
||||
pub gps_utc_offset_ns: f64,
|
||||
#[serde(rename = "last-seen", with = "chrono::serde::ts_seconds")]
|
||||
pub last_seen: DateTime,
|
||||
#[serde(rename = "leap-second-planned")]
|
||||
pub leap_second_planned: bool,
|
||||
#[serde(rename = "leap-seconds")]
|
||||
pub leap_seconds: f64,
|
||||
#[serde(rename = "utc-offset-ns")]
|
||||
pub utc_offset_ns: f64,
|
||||
}
|
||||
|
||||
impl<Message: 'static> APIService<Message> {
|
||||
pub fn api_global<F>(&self, config: &Config, callback: F) -> Option<FetchTask>
|
||||
where
|
||||
F: FnOnce(Result<Global, Error>) -> Message + 'static,
|
||||
{
|
||||
self.api_get(config, format_args!("/global.json"), callback)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash, Debug, serde_repr::Serialize_repr, serde_repr::Deserialize_repr)]
|
||||
#[repr(u8)]
|
||||
pub enum GNS {
|
||||
GPS = 0, // US
|
||||
Galileo = 2, // EU
|
||||
BeiDou = 3, // CN
|
||||
Glonass = 6, // RU
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct AlmanacEntry {
|
||||
// NOT in Glonass
|
||||
#[serde(rename = "eph-ecefX")]
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub eph_ecef_x: Option<f64>,
|
||||
#[serde(rename = "eph-ecefY")]
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub eph_ecef_y: Option<f64>,
|
||||
#[serde(rename = "eph-ecefZ")]
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub eph_ecef_z: Option<f64>,
|
||||
|
||||
// optional in Glonass
|
||||
#[serde(rename = "eph-latitude")]
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub eph_latitude: Option<f64>,
|
||||
#[serde(rename = "eph-longitude")]
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub eph_longitude: Option<f64>,
|
||||
|
||||
// NOT in Glonass
|
||||
pub t: Option<f64>,
|
||||
pub t0e: Option<f64>,
|
||||
|
||||
// all
|
||||
pub gnssid: GNS,
|
||||
pub name: String,
|
||||
pub observed: bool,
|
||||
pub inclination: f64,
|
||||
}
|
||||
|
||||
pub type Almanac = HashMap<String, AlmanacEntry>;
|
||||
|
||||
impl<Message: 'static> APIService<Message> {
|
||||
pub fn api_almanac<F>(&self, config: &Config, callback: F) -> Option<FetchTask>
|
||||
where
|
||||
F: FnOnce(Result<Almanac, Error>) -> Message + 'static,
|
||||
{
|
||||
self.api_get(config, format_args!("/almanac.json"), callback)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Observer {
|
||||
pub id: u32,
|
||||
#[serde(rename = "last-seen", with = "chrono::serde::ts_seconds")]
|
||||
pub last_seen: DateTime,
|
||||
pub latitude: f64,
|
||||
pub longitude: f64,
|
||||
#[serde(rename = "svs")]
|
||||
pub satellite_vehicles: HashMap<String, ObservedSatelliteVehicle>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct ObservedSatelliteVehicle {
|
||||
#[serde(rename = "age-s")]
|
||||
pub age_s: f32, // u32?
|
||||
pub azi: f64,
|
||||
pub db: u32,
|
||||
pub elev: f64,
|
||||
#[serde(rename = "fullName")]
|
||||
pub full_name: String,
|
||||
pub gnss: GNS,
|
||||
#[serde(rename = "last-seen")]
|
||||
pub last_seen: i64,
|
||||
pub name: String,
|
||||
pub prres: f64,
|
||||
pub sigid: u32,
|
||||
pub sv: u32,
|
||||
}
|
||||
|
||||
pub type ObserverList = Vec<Observer>;
|
||||
|
||||
impl<Message: 'static> APIService<Message> {
|
||||
pub fn api_observers<F>(&self, config: &Config, callback: F) -> Option<FetchTask>
|
||||
where
|
||||
F: FnOnce(Result<ObserverList, Error>) -> Message + 'static,
|
||||
{
|
||||
self.api_get(config, format_args!("/observers.json"), callback)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
/// A certain point in time in some reference system, in seconds
|
||||
pub struct Instant {
|
||||
pub week_number: u16, // depending on source only might have rolled on 8-bit
|
||||
pub time_of_week: u32,
|
||||
}
|
||||
|
||||
impl Instant {
|
||||
pub fn system_time(self) -> SystemTime {
|
||||
SystemTime::UNIX_EPOCH + std::time::Duration::from_secs(self.epoch())
|
||||
}
|
||||
|
||||
pub fn unroll_weeknumber(self) -> u32 {
|
||||
let current_epoch = SystemTime::now().duration_since(SystemTime::now()).expect("before 1970-01-01").as_secs();
|
||||
let current_wn = (current_epoch / (86400*7)) as u32;
|
||||
let wn = self.week_number as u32;
|
||||
let wn_bits = (16 - self.week_number.leading_zeros()).min(8); // assume at least 8-bit precision in weeknumber
|
||||
let wn_mask = !0u32 << wn_bits;
|
||||
let round_up = 1 << (wn_bits - 1); // if we already reached "halftime" round up
|
||||
wn + ((current_wn + round_up) & wn_mask) // add bits from current_wn
|
||||
}
|
||||
|
||||
pub fn epoch(self) -> u64 {
|
||||
self.unroll_weeknumber() as u64 * (86400*7) + self.time_of_week as u64
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct Vec3 {
|
||||
pub x: f64,
|
||||
pub y: f64,
|
||||
pub z: f64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ReferenceTimeOffset {
|
||||
/// offset in 2**(-30) seconds at base Instant (close to nanoseconds)
|
||||
pub base_offset: i32,
|
||||
/// correction in 2**(-50) seconds per second since base Instant
|
||||
pub correction: i32,
|
||||
/// time at which constant offset was measured
|
||||
pub base: Instant,
|
||||
/// text describing delta for some "current" (last_seen) Instant in nanoseconds offset and change in nanoseconds per day.
|
||||
pub delta: String,
|
||||
}
|
||||
|
||||
mod sv {
|
||||
use super::*;
|
||||
|
||||
adapter!{
|
||||
LastSeen => Instant {
|
||||
#[serde(rename = "wn")]
|
||||
week_number: u16,
|
||||
#[serde(rename = "tow")]
|
||||
time_of_week: u32,
|
||||
}
|
||||
}
|
||||
|
||||
adapter!{
|
||||
Position => Option<Vec3> {
|
||||
x: f64,
|
||||
y: f64,
|
||||
z: f64,
|
||||
}
|
||||
}
|
||||
|
||||
adapter!{
|
||||
UtcOffsetInstant => Option<Instant> {
|
||||
#[serde(rename = "wn0t")]
|
||||
week_number: u16,
|
||||
#[serde(rename = "t0t")]
|
||||
time_of_week: u32,
|
||||
}
|
||||
}
|
||||
|
||||
adapter!{
|
||||
// bug https://github.com/ahupowerdns/galmon/issues/8: Glonass sends a0 and a1, but not the other values
|
||||
UtcOffset => Option<ReferenceTimeOffset> {
|
||||
#[serde(rename = "a0")]
|
||||
base_offset: i32,
|
||||
#[serde(rename = "a1")]
|
||||
correction: i32,
|
||||
#[serde(flatten, with = "UtcOffsetInstant")]
|
||||
base: Instant,
|
||||
#[serde(rename = "delta-utc")]
|
||||
delta: String,
|
||||
}
|
||||
}
|
||||
|
||||
adapter!{
|
||||
GpsOffsetInstant => Option<Instant> {
|
||||
#[serde(rename = "wn0g")]
|
||||
week_number: u16,
|
||||
#[serde(rename = "t0g")]
|
||||
time_of_week: u32,
|
||||
}
|
||||
}
|
||||
|
||||
adapter!{
|
||||
GpsOffset => Option<ReferenceTimeOffset> {
|
||||
#[serde(rename = "a0g")]
|
||||
base_offset: i32,
|
||||
#[serde(rename = "a1g")]
|
||||
correction: i32,
|
||||
#[serde(flatten, with = "GpsOffsetInstant")]
|
||||
base: Instant,
|
||||
#[serde(rename = "delta-gps")]
|
||||
delta: String,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: "undo" flatten #[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct SatelliteVehicle {
|
||||
/* Identification: */
|
||||
gnssid: GNS,
|
||||
svid: u32, /* vehicle id; can be moved between satellites */
|
||||
sigid: u32, /* "signal", also appended as "@{sigid}" to the full name */
|
||||
/* Data: */
|
||||
/// Signal In Space Accuracy
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
sisa: Option<String>,
|
||||
#[serde(rename = "eph-age-m", default, skip_serializing_if = "Option::is_none")]
|
||||
/// Age of ephemeris in minutes
|
||||
eph_age_m: Option<f32>,
|
||||
|
||||
#[serde(rename = "best-tle", default, skip_serializing_if = "Option::is_none")]
|
||||
best_tle: Option<String>,
|
||||
#[serde(rename = "best-tle-dist", default, skip_serializing_if = "Option::is_none")]
|
||||
best_tle_dist: Option<f64>,
|
||||
#[serde(rename = "best-tle-int-desig", default, skip_serializing_if = "Option::is_none")]
|
||||
best_tle_int_desig: Option<String>,
|
||||
#[serde(rename = "best-tle-norad", default, skip_serializing_if = "Option::is_none")]
|
||||
best_tle_norad: Option<i32>,
|
||||
|
||||
#[serde(rename = "alma-dist", default, skip_serializing_if = "Option::is_none")]
|
||||
alma_dist: Option<f64>, // distance from almanac position in kilometers
|
||||
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
aode: Option<u32>,
|
||||
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
aodc: Option<u32>,
|
||||
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
iod: Option<u16>,
|
||||
// IOD data:
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
af0: Option<i32>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
af1: Option<i32>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
af2: Option<u8>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
t0c: Option<u16>, // clock epoch
|
||||
|
||||
#[serde(flatten, with = "sv::Position")]
|
||||
position: Option<Vec3>,
|
||||
|
||||
// utc offset (all but Glonass): combined data
|
||||
#[serde(flatten, with = "sv::UtcOffset")]
|
||||
utc_offset: Option<ReferenceTimeOffset>,
|
||||
|
||||
// GPS offset (only Galileo and BeiDou)
|
||||
#[serde(flatten, with = "sv::GpsOffset")]
|
||||
gpc_offset: Option<ReferenceTimeOffset>,
|
||||
|
||||
#[serde(rename = "dtLS")]
|
||||
dt_ls: i8,
|
||||
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
health: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
healthissue: Option<u32>, // some codes?
|
||||
|
||||
// Galileo only: Health flags for E1 (common) and E5 (uncommon) frequencies.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
e1bhs: Option<u8>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
e1bdvs: Option<bool>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
e5bhs: Option<u8>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
e5bdvs: Option<bool>,
|
||||
|
||||
#[serde(rename = "latest-disco", default, skip_serializing_if = "Option::is_none")]
|
||||
latest_disco: Option<f64>,
|
||||
#[serde(rename = "latest-disco-age", default, skip_serializing_if = "Option::is_none")]
|
||||
latest_disco_age: Option<f64>,
|
||||
|
||||
#[serde(rename = "time-disco", default, skip_serializing_if = "Option::is_none")]
|
||||
time_disco: Option<f64>,
|
||||
|
||||
#[serde(flatten, with = "sv::LastSeen")]
|
||||
last_seen: Instant,
|
||||
|
||||
/// Number of seconds since we've last received from this SV. A satellite can be out of sight for a long time
|
||||
#[serde(rename = "last-seen-s")]
|
||||
last_seen_s: i64,
|
||||
|
||||
#[serde(rename = "fullName")]
|
||||
full_name: String, // format!("{}@{}", self.name, self.sigid)
|
||||
name: String,
|
||||
|
||||
perrecv: HashMap<u32, SatelliteVehiclePerReceiver>, // keys: Observer `id`
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct SatelliteVehiclePerReceiver {
|
||||
#[serde(rename = "elev")]
|
||||
elevation: f64,
|
||||
#[serde(rename = "azi", default, skip_serializing_if = "Option::is_none")]
|
||||
azimuth: Option<f64>,
|
||||
db: i32,
|
||||
#[serde(rename = "last-seen-s")]
|
||||
last_seen_s: i64,
|
||||
prres: f64,
|
||||
delta_hz: Option<f64>,
|
||||
delta_hz_corr: Option<f64>,
|
||||
}
|
||||
|
||||
pub type SatelliteVehicles = HashMap<String, SatelliteVehicle>;
|
||||
|
||||
impl<Message: 'static> APIService<Message> {
|
||||
pub fn api_satellite_vehicles<F>(&self, config: &Config, callback: F) -> Option<FetchTask>
|
||||
where
|
||||
F: FnOnce(Result<SatelliteVehicles, Error>) -> Message + 'static,
|
||||
{
|
||||
self.api_get(config, format_args!("/svs.json"), callback)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
use serde::{Serialize, Deserialize};
|
||||
use std::fmt;
|
||||
|
||||
macro_rules! tagtype {
|
||||
($name:ident: $tag:literal) => {
|
||||
#[derive(Clone, Copy, Default, Debug)]
|
||||
pub struct $name;
|
||||
|
||||
impl Serialize for $name {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
serializer.serialize_str($tag)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for $name {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
struct Visitor;
|
||||
impl serde::de::Visitor<'_> for Visitor {
|
||||
type Value = $name;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(formatter, "tag type {:?}", $tag)
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
if v != $tag {
|
||||
return Err(E::invalid_value(serde::de::Unexpected::Str(v), &$tag));
|
||||
}
|
||||
Ok($name)
|
||||
}
|
||||
|
||||
}
|
||||
deserializer.deserialize_str(Visitor)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
tagtype!(TagFeatureCollection: "FeatureCollection");
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct FeatureCollection {
|
||||
pub r#type: TagFeatureCollection,
|
||||
pub features: Vec<Feature>,
|
||||
}
|
||||
|
||||
tagtype!(TagFeature: "Feature");
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Feature {
|
||||
pub r#type: TagFeature,
|
||||
pub id: String,
|
||||
pub properties: FeatureProperties,
|
||||
pub geometry: Geometry,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct FeatureProperties {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum Geometry {
|
||||
Polygon {
|
||||
coordinates: PolygonData,
|
||||
},
|
||||
MultiPolygon {
|
||||
coordinates: Vec<PolygonData>,
|
||||
},
|
||||
}
|
||||
|
||||
// first list of points is outer "hull" (should be clockwise), remaining list of points are holes (counterclockwise)
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct PolygonData(pub Vec<Vec<Position>>);
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct Position {
|
||||
pub longitude: f32,
|
||||
pub latitude: f32,
|
||||
}
|
||||
|
||||
impl Serialize for Position {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
(self.longitude, self.latitude).serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Position {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
<(f32, f32)>::deserialize(deserializer).map(|(longitude, latitude)| Position { longitude, latitude })
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
use serde::{Serialize, Deserialize};
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct ConfigData {
|
||||
pub base_url: String,
|
||||
}
|
||||
|
||||
pub type Config = Rc<ConfigData>;
|
|
@ -0,0 +1,42 @@
|
|||
#![recursion_limit="512"]
|
||||
|
||||
#[macro_use]
|
||||
extern crate stdweb;
|
||||
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! jslog {
|
||||
($($tt:tt)*) => {
|
||||
$crate::log(&format!($($tt)*));
|
||||
};
|
||||
}
|
||||
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! jserror {
|
||||
($($tt:tt)*) => {
|
||||
$crate::error(&format!($($tt)*));
|
||||
};
|
||||
}
|
||||
|
||||
pub mod api;
|
||||
pub mod config;
|
||||
pub mod models;
|
||||
pub mod ui;
|
||||
pub mod uitools;
|
||||
pub mod utils;
|
||||
|
||||
#[inline(never)]
|
||||
fn log(message: &str) {
|
||||
yew::services::ConsoleService::new().log(message);
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
#[allow(unused)]
|
||||
fn error(message: &str) {
|
||||
yew::services::ConsoleService::new().error(message);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
yew::start_app::<ui::app::MainApp>();
|
||||
}
|
||||
|
||||
// https://galmon.eu/observers.json
|
|
@ -0,0 +1,48 @@
|
|||
use crate::api;
|
||||
use crate::config::Config;
|
||||
use crate::models::helper::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AlmanacT {
|
||||
config: Config,
|
||||
}
|
||||
|
||||
impl Model for AlmanacT {
|
||||
type FetchData = api::Almanac;
|
||||
const NAME: &'static str = "Almanac";
|
||||
|
||||
fn refresh(sr: &ModelHandle<Self>) -> Option<api::FetchTask> {
|
||||
let sref = sr.clone();
|
||||
let sd = sr.data();
|
||||
sr.service().api_almanac(&sd.config, move |result| {
|
||||
sref.set_received(result);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct Almanac(pub(super) ModelHandle<AlmanacT>);
|
||||
|
||||
impl std::ops::Deref for Almanac {
|
||||
type Target = ModelHandle<AlmanacT>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Almanac {
|
||||
pub fn new(config: Config) -> Self {
|
||||
Self(ModelHandle::new(
|
||||
AlmanacT { config },
|
||||
(),
|
||||
))
|
||||
}
|
||||
|
||||
pub(super) fn new_shared(config: Config, base: ModelBase) -> Self {
|
||||
Self(ModelHandle::new(
|
||||
AlmanacT { config },
|
||||
base,
|
||||
))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
use crate::config::Config;
|
||||
use crate::models::almanac::Almanac;
|
||||
use crate::models::global::Global;
|
||||
use crate::models::helper::{Callbacks, CallbackRegistration, ModelBase};
|
||||
use crate::models::observers::Observers;
|
||||
use std::cell::Cell;
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Watch {
|
||||
almanac: Almanac,
|
||||
almanac_waiting: Cell<bool>,
|
||||
global: Global,
|
||||
global_waiting: Cell<bool>,
|
||||
observers: Observers,
|
||||
observers_waiting: Cell<bool>,
|
||||
callbacks: Callbacks,
|
||||
}
|
||||
|
||||
impl Watch {
|
||||
fn on_almanac_update(&self) {
|
||||
self.almanac_waiting.set(false);
|
||||
self.on_generic_update();
|
||||
}
|
||||
|
||||
fn on_global_update(&self) {
|
||||
self.global_waiting.set(false);
|
||||
self.on_generic_update();
|
||||
}
|
||||
|
||||
fn on_observers_update(&self) {
|
||||
self.observers_waiting.set(false);
|
||||
self.on_generic_update();
|
||||
}
|
||||
|
||||
fn on_generic_update(&self) {
|
||||
if !self.almanac_waiting.get() && !self.global_waiting.get() && !self.observers_waiting.get() {
|
||||
self.callbacks.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Inner {
|
||||
watch: Rc<Watch>,
|
||||
_almanac_cbr: CallbackRegistration,
|
||||
_global_cbr: CallbackRegistration,
|
||||
_observers_cbr: CallbackRegistration,
|
||||
}
|
||||
|
||||
/// All basic data
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Base(Rc<Inner>);
|
||||
|
||||
impl Base {
|
||||
pub fn new(config: Config) -> Self {
|
||||
let base = ModelBase::from(());
|
||||
let watch = Rc::new(Watch {
|
||||
almanac: Almanac::new_shared(config.clone(), base.clone()),
|
||||
almanac_waiting: Cell::new(true),
|
||||
global: Global::new_shared(config.clone(), base.clone()),
|
||||
global_waiting: Cell::new(true),
|
||||
observers: Observers::new_shared(config, base),
|
||||
observers_waiting: Cell::new(true),
|
||||
callbacks: Callbacks::new(),
|
||||
});
|
||||
|
||||
let _almanac_cbr = watch.almanac.register(yew::Callback::from({
|
||||
let watch = watch.clone();
|
||||
move |()| watch.on_almanac_update()
|
||||
}));
|
||||
let _global_cbr = watch.global.register(yew::Callback::from({
|
||||
let watch = watch.clone();
|
||||
move |()| watch.on_global_update()
|
||||
}));
|
||||
let _observers_cbr = watch.observers.register(yew::Callback::from({
|
||||
let watch = watch.clone();
|
||||
move |()| watch.on_observers_update()
|
||||
}));
|
||||
|
||||
let inner = Rc::new(Inner {
|
||||
watch,
|
||||
_almanac_cbr,
|
||||
_global_cbr,
|
||||
_observers_cbr,
|
||||
});
|
||||
|
||||
Self(inner)
|
||||
}
|
||||
|
||||
pub fn register(&self, callback: yew::Callback<()>) -> CallbackRegistration {
|
||||
self.0.watch.callbacks.register(callback)
|
||||
}
|
||||
|
||||
pub fn refresh(&self) {
|
||||
self.0.watch.almanac_waiting.set(true);
|
||||
self.0.watch.global_waiting.set(true);
|
||||
self.0.watch.observers_waiting.set(true);
|
||||
|
||||
self.0.watch.almanac.refresh();
|
||||
self.0.watch.global.refresh();
|
||||
self.0.watch.observers.refresh();
|
||||
}
|
||||
|
||||
pub fn is_pending(&self) -> bool {
|
||||
self.0.watch.almanac.is_pending()
|
||||
|| self.0.watch.global.is_pending()
|
||||
|| self.0.watch.observers.is_pending()
|
||||
}
|
||||
|
||||
pub fn almanac(&self) -> &Almanac {
|
||||
&self.0.watch.almanac
|
||||
}
|
||||
|
||||
pub fn global(&self) -> &Global {
|
||||
&self.0.watch.global
|
||||
}
|
||||
|
||||