init
This commit is contained in:
commit
e3dceb8e20
|
|
@ -0,0 +1 @@
|
||||||
|
/target
|
||||||
|
|
@ -0,0 +1,753 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ahash"
|
||||||
|
version = "0.8.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
"version_check",
|
||||||
|
"zerocopy",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "allocator-api2"
|
||||||
|
version = "0.2.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.83"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cassowary"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "castaway"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a17ed5635fc8536268e5d4de1e22e81ac34419e5f052d4d51f4e01dcc263fcc"
|
||||||
|
dependencies = [
|
||||||
|
"rustversion",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "compact_str"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f86b9c4c00838774a6d902ef931eff7470720c51d90c2e32cfe15dc304737b3f"
|
||||||
|
dependencies = [
|
||||||
|
"castaway",
|
||||||
|
"cfg-if",
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"static_assertions",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossterm"
|
||||||
|
version = "0.25.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"crossterm_winapi",
|
||||||
|
"libc",
|
||||||
|
"mio",
|
||||||
|
"parking_lot",
|
||||||
|
"signal-hook",
|
||||||
|
"signal-hook-mio",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossterm"
|
||||||
|
version = "0.27.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.5.0",
|
||||||
|
"crossterm_winapi",
|
||||||
|
"libc",
|
||||||
|
"mio",
|
||||||
|
"parking_lot",
|
||||||
|
"signal-hook",
|
||||||
|
"signal-hook-mio",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossterm_winapi"
|
||||||
|
version = "0.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "equivalent"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.14.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
"allocator-api2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "2.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
|
||||||
|
dependencies = [
|
||||||
|
"equivalent",
|
||||||
|
"hashbrown",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indoc"
|
||||||
|
version = "2.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.154"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lock_api"
|
||||||
|
version = "0.4.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"scopeguard",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lru"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc"
|
||||||
|
dependencies = [
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mio"
|
||||||
|
version = "0.8.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
"wasi",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.19.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot"
|
||||||
|
version = "0.12.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api",
|
||||||
|
"parking_lot_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot_core"
|
||||||
|
version = "0.9.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"redox_syscall",
|
||||||
|
"smallvec",
|
||||||
|
"windows-targets 0.52.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "paste"
|
||||||
|
version = "1.0.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.82"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.36"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ratatui"
|
||||||
|
version = "0.26.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a564a852040e82671dc50a37d88f3aa83bbc690dfc6844cfe7a2591620206a80"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.5.0",
|
||||||
|
"cassowary",
|
||||||
|
"compact_str",
|
||||||
|
"crossterm 0.27.0",
|
||||||
|
"indoc",
|
||||||
|
"itertools",
|
||||||
|
"lru",
|
||||||
|
"paste",
|
||||||
|
"stability",
|
||||||
|
"strum",
|
||||||
|
"unicode-segmentation",
|
||||||
|
"unicode-width",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_syscall"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.5.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "req"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"crossterm 0.27.0",
|
||||||
|
"indexmap",
|
||||||
|
"ratatui",
|
||||||
|
"rsn",
|
||||||
|
"serde",
|
||||||
|
"serde_yaml",
|
||||||
|
"stringlit",
|
||||||
|
"toml",
|
||||||
|
"tui",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rsn"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "673e95b85078271a8eb13f152a0adfd36390f2cbc7e74b0ff9dc7abb38ae9412"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "092474d1a01ea8278f69e6a358998405fae5b8b963ddaeb2b0b04a128bf1dfb0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.201"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.201"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_spanned"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_yaml"
|
||||||
|
version = "0.9.34+deprecated"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
"unsafe-libyaml",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook"
|
||||||
|
version = "0.3.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"signal-hook-registry",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook-mio"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"mio",
|
||||||
|
"signal-hook",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook-registry"
|
||||||
|
version = "1.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smallvec"
|
||||||
|
version = "1.13.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stability"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2ff9eaf853dec4c8802325d8b6d3dffa86cc707fd7a1a4cdbf416e13b061787a"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "static_assertions"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stringlit"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e80de30f6a4915f4277c75980dea789ea6b895039ce61ad2a3b79a8787e7ada1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strum"
|
||||||
|
version = "0.26.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29"
|
||||||
|
dependencies = [
|
||||||
|
"strum_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strum_macros"
|
||||||
|
version = "0.26.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"rustversion",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.61"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.8.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"toml_edit",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_datetime"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_edit"
|
||||||
|
version = "0.22.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tui"
|
||||||
|
version = "0.19.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ccdd26cbd674007e649a272da4475fb666d3aa0ad0531da7136db6fab0e5bad1"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"cassowary",
|
||||||
|
"crossterm 0.25.0",
|
||||||
|
"unicode-segmentation",
|
||||||
|
"unicode-width",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-segmentation"
|
||||||
|
version = "1.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-width"
|
||||||
|
version = "0.1.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unsafe-libyaml"
|
||||||
|
version = "0.2.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu",
|
||||||
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.48.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets 0.48.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm 0.48.5",
|
||||||
|
"windows_aarch64_msvc 0.48.5",
|
||||||
|
"windows_i686_gnu 0.48.5",
|
||||||
|
"windows_i686_msvc 0.48.5",
|
||||||
|
"windows_x86_64_gnu 0.48.5",
|
||||||
|
"windows_x86_64_gnullvm 0.48.5",
|
||||||
|
"windows_x86_64_msvc 0.48.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.52.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm 0.52.5",
|
||||||
|
"windows_aarch64_msvc 0.52.5",
|
||||||
|
"windows_i686_gnu 0.52.5",
|
||||||
|
"windows_i686_gnullvm",
|
||||||
|
"windows_i686_msvc 0.52.5",
|
||||||
|
"windows_x86_64_gnu 0.52.5",
|
||||||
|
"windows_x86_64_gnullvm 0.52.5",
|
||||||
|
"windows_x86_64_msvc 0.52.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.52.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.52.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.52.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnullvm"
|
||||||
|
version = "0.52.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.52.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.52.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.52.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.52.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "0.6.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3c52e9c97a68071b23e836c9380edae937f17b9c4667bd021973efc689f618d"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy"
|
||||||
|
version = "0.7.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087"
|
||||||
|
dependencies = [
|
||||||
|
"zerocopy-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy-derive"
|
||||||
|
version = "0.7.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
[package]
|
||||||
|
name = "req"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow = "1.0.83"
|
||||||
|
crossterm = "0.27.0"
|
||||||
|
indexmap = { version = "2.2.6", features = ["serde"] }
|
||||||
|
ratatui = "0.26.2"
|
||||||
|
rsn = "0.1.0"
|
||||||
|
serde = { version = "1.0.201", features = ["derive"] }
|
||||||
|
serde_yaml = "0.9.34"
|
||||||
|
stringlit = "2.1.0"
|
||||||
|
toml = { version = "0.8.12", features = ["indexmap", "preserve_order"] }
|
||||||
|
tui = "0.19.0"
|
||||||
|
|
@ -0,0 +1,134 @@
|
||||||
|
# Requirements for journal-uploader
|
||||||
|
|
||||||
|
[[_TOC_]]
|
||||||
|
|
||||||
|
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED",
|
||||||
|
"MAY", and "OPTIONAL" in this document are to be interpreted as described in
|
||||||
|
[RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119).
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
The journal-uploader has two main functionalities.
|
||||||
|
- Take a stream of log messages and filter them depending on their severity
|
||||||
|
- Upload journal logs for a specified time when activated through cloud call
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
### 1. Traced Logging
|
||||||
|
#### 1.1 File Monitoring
|
||||||
|
- **1.1.1 Continuous Monitoring:** The tool **_MUST_** continuously monitor a designated directory.
|
||||||
|
|
||||||
|
#### 1.2 File Detection
|
||||||
|
- **1.2.1 Detection of New Files:** The tool **_MUST_** detect the addition of new files in the monitored directory.
|
||||||
|
- **1.2.2 Avoid Re-processing:** The tool **_MUST NOT_** process files that have already been processed.
|
||||||
|
|
||||||
|
#### 1.3 File Processing
|
||||||
|
- **1.3.1 Reading Log Messages:** When a new file is processed, each log message **_SHOULD_** be put into a buffer.
|
||||||
|
- **1.3.2 Filtering Log Messages:** The tool will search for messages of a defined priority (Trigger Priority).
|
||||||
|
Each message of this priority, as well as all messages before and after, which are inside a defined timespan, **_MUST_**
|
||||||
|
get written into a file. Every other message **_SHOULD_** gets dropped.
|
||||||
|
- **1.3.3 No Duplicate Log Messages:** The tool **_SHALL_** make sure that no log entry will be written to the file twice.
|
||||||
|
|
||||||
|
#### 1.4 Traced Log Rotation
|
||||||
|
- **1.4.1 Rotating Files:** When the size of the current traced log file exceeds a certain threshold,
|
||||||
|
it **_MUST_** be closed and a new file **_MUST_** be opened for writing.
|
||||||
|
- **1.4.2 Compression of Rotated Files:** Each traced log file **_MUST_** get compressed after it got rotated.
|
||||||
|
- **1.4.3 Rotating Directory:** When the directory size exceeds a certain threshold, the tool **_MUST_** delete the oldest
|
||||||
|
files in the directory, until the size is below the threshold again.
|
||||||
|
|
||||||
|
### 2. Remote Journal Logging
|
||||||
|
#### 2.1 Service Activation
|
||||||
|
- **2.1.1 Cloud Activation:** The remote journal logging **_SHALL_** be startable through a function call from the cloud.
|
||||||
|
The api call has the duration and max interval as arguments.
|
||||||
|
- **2.1.2 Duration:** The remote journal logging **_SHOULD_** stay active, until it reaches the specified duration.
|
||||||
|
- **2.1.3 Max Interval:** If no upload was done after the amount of time specified in max interval,
|
||||||
|
a log rotation **_SHALL_** be triggered, which will in turn get picked up by the file monitoring.
|
||||||
|
- **2.1.4 Analytics Not Accepted:** If the user has not accepted the usage of their data, the cloud call **_MUST_**
|
||||||
|
result in an error.
|
||||||
|
|
||||||
|
#### 2.2 File Monitoring
|
||||||
|
- **2.2.1 Continuous Monitoring:** The tool **_SHOULD_** continuously monitor a designated directory.
|
||||||
|
|
||||||
|
#### 2.3 File Detection
|
||||||
|
- **2.3.1 Detection of New Files:** The tool **_MUST_** detect the addition of new files in the monitored directory.
|
||||||
|
- **2.3.2 Avoid Re-processing:** The tool **_MUST NOT_** process files that have already been processed.
|
||||||
|
|
||||||
|
#### 2.4 File Processing
|
||||||
|
- **2.4.1 File Upload:** When a file gets detected, it **_SHOULD_** get uploaded to the cloud.
|
||||||
|
- **2.4.2 No Duplicate Files:** Already processed files **_MUST NOT_** get uploaded again.
|
||||||
|
- **2.4.3 Revoking Analytics:** If the user revokes the usage of their data, the service **_MAY_** continue running
|
||||||
|
but **_MUST NOT_** upload any data until the user allows the usage of their data again.
|
||||||
|
- **2.4.4 Duration Expired:** After the specified duration is expired, the service **_SHOULD_** stop uploading files.
|
||||||
|
|
||||||
|
### 3. Configuration
|
||||||
|
- **3.1 Configurable Journal Directory:** Users **_SHOULD_** be able to specify the directory to be monitored for
|
||||||
|
journal files.
|
||||||
|
- Required: This value **_MUST_** be provided as a start parameter.
|
||||||
|
- **3.2 Configurable Output Directory:** Users **_SHOULD_** be able to specify the directory into which the final files
|
||||||
|
will be written.
|
||||||
|
- Required: This value **_MUST_** be provided as a start parameter.
|
||||||
|
- **3.3 Configurable Trigger Priority:** Users **_SHOULD_** be able to specify which priority triggers the filtering.
|
||||||
|
- Default Value: _Warning_
|
||||||
|
- **3.4 Configurable Journal Context:** Users **_SHOULD_** be able to specify how many seconds of context will be added
|
||||||
|
to traced logs when encountering a trigger priority.
|
||||||
|
- Default Value: _10_
|
||||||
|
- **3.5 Configurable Max File Size:** Users **_SHOULD_** be able to specify the max file size, at which a file gets rotated.
|
||||||
|
- Default Value: _8388608_ (8 MB)
|
||||||
|
- **3.6 Configurable Max Directory Size:** Users **_SHOULD_** be able to specify the max directory size, at which a
|
||||||
|
directory gets rotated.
|
||||||
|
- Default Value: _75497472_ (72 MB)
|
||||||
|
- **3.7 Configurable File Monitoring Interval:** Users **_SHOULD_** be able to specify an interval, which **_SHOULD_** change
|
||||||
|
how long the tool waits before checking if new files are available.
|
||||||
|
- Default Value: _10_
|
||||||
|
|
||||||
|
### 4. Performance Requirements
|
||||||
|
- **4.1 Efficiency:** The tool **_SHOULD_** efficiently monitor and process files without excessive resource consumption.
|
||||||
|
- **4.2 Interval Delay:** The tool **_SHOULD_** do its work with no more than 10 seconds delay after its interval.
|
||||||
|
|
||||||
|
### 5. Data Protection
|
||||||
|
- **5.1 No Insecure Connection:** The tool **_MUST_** send data only through a secure connection.
|
||||||
|
- **5.2 GDPR compliance:** The tool **_MUST NOT_** upload data if the user has not agreed to share this information.
|
||||||
|
|
||||||
|
### 6. Testing
|
||||||
|
- **6.1 Unit Tests:** Comprehensive unit tests **_SHOULD_** be written to cover major functionalities.
|
||||||
|
- **6.2 Integration Tests:** Integration tests **_SHOULD_** be conducted to ensure all parts of the tool work together
|
||||||
|
seamlessly.
|
||||||
|
|
||||||
|
## Definitions
|
||||||
|
- Default Journal Directory: /run/log/journal/<machine_id>
|
||||||
|
- Machine ID can be found at /etc/machine-id
|
||||||
|
- Default Output Directory: /run/log/filtered-journal
|
||||||
|
|
||||||
|
## Config Defaults
|
||||||
|
|
||||||
|
- **Journal Directory**
|
||||||
|
- type: Path
|
||||||
|
- **Required**: This value **_MUST_** be provided as a start parameter.
|
||||||
|
|
||||||
|
- **Output Directory**
|
||||||
|
- type: Path
|
||||||
|
- **Required**: This value **_MUST_** be provided as a start parameter.
|
||||||
|
|
||||||
|
- **Trigger Priority**
|
||||||
|
- type: Enum
|
||||||
|
- Valid Values: _Emergency, Alert, Critical, Error, Warning, Notice, Info, Debug_
|
||||||
|
- Default Value: _Warning_
|
||||||
|
|
||||||
|
- **Journal Context**
|
||||||
|
- type: Integer
|
||||||
|
- unit: Seconds
|
||||||
|
- Default Value: _15_
|
||||||
|
|
||||||
|
- **Max File Size**
|
||||||
|
- type: Integer
|
||||||
|
- unit: Bytes
|
||||||
|
- Default Value: _8388608_ (8 MB)
|
||||||
|
|
||||||
|
- **Max Directory Size**
|
||||||
|
- type: Integer
|
||||||
|
- unit: Bytes
|
||||||
|
- Default Value: _75497472_ (72 MB)
|
||||||
|
|
||||||
|
- **File Monitoring Interval**
|
||||||
|
- type: Integer
|
||||||
|
- unit: Seconds
|
||||||
|
- Default Value: _10_
|
||||||
|
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
name: journal-uploader
|
||||||
|
description: |-
|
||||||
|
The journal-uploader has two main functionalities.
|
||||||
|
- Take a stream of log messages and filter them depending on their severity
|
||||||
|
- Upload journal logs for a specified time when activated through cloud call
|
||||||
|
topics:
|
||||||
|
FEAT-1:
|
||||||
|
name: Traced Logging
|
||||||
|
subtopics:
|
||||||
|
SUB-1:
|
||||||
|
name: File Monitoring
|
||||||
|
requirements:
|
||||||
|
REQ-1:
|
||||||
|
name: Continuous Monitoring
|
||||||
|
description: The tool must continuously monitor a designated directory.
|
||||||
|
definitions:
|
||||||
|
- name: Default Journal Directory
|
||||||
|
value: /run/log/journal/<machine_id>
|
||||||
|
additional_info:
|
||||||
|
- Machine ID can be found at /etc/machine-id
|
||||||
|
- name: Default Output Directory
|
||||||
|
value: /run/log/filtered-journal
|
||||||
|
config_defaults:
|
||||||
|
- name: Journal Directory
|
||||||
|
type: Path
|
||||||
|
- name: Output Directory
|
||||||
|
type: Path
|
||||||
|
- name: Trigger Priority
|
||||||
|
type: Enum
|
||||||
|
valid_values:
|
||||||
|
- Emergency
|
||||||
|
- Alert
|
||||||
|
- Critical
|
||||||
|
- Error
|
||||||
|
- Warning
|
||||||
|
- Notice
|
||||||
|
- Info
|
||||||
|
- Debug
|
||||||
|
default_value: Warning
|
||||||
|
- name: Journal Context
|
||||||
|
type: Integer
|
||||||
|
unit: Seconds
|
||||||
|
default_value: '15'
|
||||||
|
- name: Max File Size
|
||||||
|
type: Integer
|
||||||
|
unit: Bytes
|
||||||
|
default_value: '8388608'
|
||||||
|
hint: (8 MB)
|
||||||
|
- name: Max Directory Size
|
||||||
|
type: Integer
|
||||||
|
unit: Bytes
|
||||||
|
default_value: '75497472'
|
||||||
|
hint: (72 MB)
|
||||||
|
- name: File Monitoring Interval
|
||||||
|
type: Integer
|
||||||
|
unit: Seconds
|
||||||
|
default_value: '10'
|
||||||
|
|
@ -0,0 +1,179 @@
|
||||||
|
use crossterm::{
|
||||||
|
event::{self, Event as CEvent, KeyCode},
|
||||||
|
execute,
|
||||||
|
style::Color,
|
||||||
|
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
|
||||||
|
};
|
||||||
|
use indexmap::indexmap;
|
||||||
|
use ratatui::{
|
||||||
|
backend::CrosstermBackend,
|
||||||
|
layout::{Constraint, Direction, Layout},
|
||||||
|
prelude::Style,
|
||||||
|
widgets::{Block, Borders, List, ListItem, ListState},
|
||||||
|
Terminal,
|
||||||
|
};
|
||||||
|
use stringlit::s;
|
||||||
|
|
||||||
|
use std::io;
|
||||||
|
use std::sync::mpsc;
|
||||||
|
use std::thread;
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
|
use req::*;
|
||||||
|
|
||||||
|
enum Event<I> {
|
||||||
|
Input(I),
|
||||||
|
Tick,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct App {
|
||||||
|
project: Project,
|
||||||
|
topics_list_state: ListState,
|
||||||
|
requirements_list_state: ListState,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl App {
|
||||||
|
fn new(project: Project) -> App {
|
||||||
|
let mut topics_list_state = ListState::default();
|
||||||
|
topics_list_state.select(Some(0));
|
||||||
|
|
||||||
|
let mut requirements_list_state = ListState::default();
|
||||||
|
requirements_list_state.select(Some(0));
|
||||||
|
|
||||||
|
App {
|
||||||
|
project,
|
||||||
|
topics_list_state,
|
||||||
|
requirements_list_state,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw(&mut self, f: &mut ratatui::Frame) {
|
||||||
|
let chunks = Layout::default()
|
||||||
|
.direction(Direction::Vertical)
|
||||||
|
.margin(1)
|
||||||
|
.constraints(
|
||||||
|
[
|
||||||
|
Constraint::Percentage(10), // Project Title
|
||||||
|
Constraint::Percentage(45), // Topics List
|
||||||
|
Constraint::Percentage(45), // Requirements List
|
||||||
|
]
|
||||||
|
.as_ref(),
|
||||||
|
)
|
||||||
|
.split(f.size());
|
||||||
|
|
||||||
|
let project_title = Block::default()
|
||||||
|
.title(self.project.name.clone())
|
||||||
|
.borders(Borders::ALL);
|
||||||
|
f.render_widget(project_title, chunks[0]);
|
||||||
|
|
||||||
|
let topics: Vec<ListItem> = self
|
||||||
|
.project
|
||||||
|
.topics
|
||||||
|
.iter()
|
||||||
|
.map(|(name, _)| ListItem::new(name.clone()))
|
||||||
|
.collect();
|
||||||
|
let topics_list = List::new(topics)
|
||||||
|
.block(Block::default().borders(Borders::ALL).title("Topics"))
|
||||||
|
.highlight_style(Style::default().bg(Color::Blue.into()));
|
||||||
|
f.render_stateful_widget(topics_list, chunks[1], &mut self.topics_list_state);
|
||||||
|
|
||||||
|
let requirements: Vec<ListItem> = self
|
||||||
|
.project
|
||||||
|
.topics
|
||||||
|
.first()
|
||||||
|
.unwrap()
|
||||||
|
.1
|
||||||
|
.requirements
|
||||||
|
.iter()
|
||||||
|
.map(|(name, _)| ListItem::new(name.clone()))
|
||||||
|
.collect();
|
||||||
|
let requirements_list = List::new(requirements)
|
||||||
|
.block(Block::default().borders(Borders::ALL).title("Requirements"))
|
||||||
|
.highlight_style(Style::default().bg(Color::Yellow.into()));
|
||||||
|
f.render_stateful_widget(
|
||||||
|
requirements_list,
|
||||||
|
chunks[2],
|
||||||
|
&mut self.requirements_list_state,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_topic(&mut self) {
|
||||||
|
let n = self.project.topics.len();
|
||||||
|
if let Some(i) = self.topics_list_state.selected() {
|
||||||
|
if i >= n - 1 {
|
||||||
|
self.topics_list_state.select(Some(0));
|
||||||
|
} else {
|
||||||
|
self.topics_list_state.select(Some(i + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn previous_topic(&mut self) {
|
||||||
|
let n = self.project.topics.len();
|
||||||
|
if let Some(i) = self.topics_list_state.selected() {
|
||||||
|
if i == 0 {
|
||||||
|
self.topics_list_state.select(Some(n - 1));
|
||||||
|
} else {
|
||||||
|
self.topics_list_state.select(Some(i - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
enable_raw_mode()?;
|
||||||
|
let mut stdout = io::stdout();
|
||||||
|
execute!(stdout, EnterAlternateScreen)?;
|
||||||
|
|
||||||
|
let backend = CrosstermBackend::new(stdout);
|
||||||
|
let mut terminal = Terminal::new(backend)?;
|
||||||
|
|
||||||
|
let project = demo_project();
|
||||||
|
|
||||||
|
let mut app = App::new(project);
|
||||||
|
|
||||||
|
let (tx, rx) = mpsc::channel();
|
||||||
|
let tick_rate = Duration::from_millis(200);
|
||||||
|
thread::spawn(move || {
|
||||||
|
let mut last_tick = Instant::now();
|
||||||
|
loop {
|
||||||
|
let timeout = tick_rate
|
||||||
|
.checked_sub(last_tick.elapsed())
|
||||||
|
.unwrap_or_else(|| Duration::from_secs(0));
|
||||||
|
if event::poll(timeout).expect("poll works") {
|
||||||
|
if let CEvent::Key(key) = event::read().expect("read works") {
|
||||||
|
tx.send(Event::Input(key)).expect("send works");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if last_tick.elapsed() >= tick_rate {
|
||||||
|
tx.send(Event::Tick).expect("tick works");
|
||||||
|
last_tick = Instant::now();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
loop {
|
||||||
|
terminal.draw(|f| app.draw(f))?;
|
||||||
|
|
||||||
|
match rx.recv()? {
|
||||||
|
Event::Input(event) => match event.code {
|
||||||
|
KeyCode::Char('q') => {
|
||||||
|
disable_raw_mode()?;
|
||||||
|
execute!(terminal.backend_mut(), LeaveAlternateScreen)?;
|
||||||
|
terminal.show_cursor()?;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
KeyCode::Down => {
|
||||||
|
app.next_topic();
|
||||||
|
}
|
||||||
|
KeyCode::Up => {
|
||||||
|
app.previous_topic();
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
Event::Tick => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,193 @@
|
||||||
|
use indexmap::{indexmap, IndexMap};
|
||||||
|
use serde::{Deserialize, Serialize, Serializer};
|
||||||
|
use stringlit::s;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub const WORD_DESCRIPTION: &str = //
|
||||||
|
r#"The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED",
|
||||||
|
"MAY", and "OPTIONAL" in this document are to be interpreted as described in
|
||||||
|
[RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119).
|
||||||
|
"#;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub const HIGHLIGHTED_WORDS: [&str; 10] = [
|
||||||
|
"must not",
|
||||||
|
"must",
|
||||||
|
"required",
|
||||||
|
"shall not",
|
||||||
|
"shall",
|
||||||
|
"should not",
|
||||||
|
"should",
|
||||||
|
"recommended",
|
||||||
|
"may",
|
||||||
|
"optional",
|
||||||
|
];
|
||||||
|
|
||||||
|
pub fn my_trim<S>(v: &String, s: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
s.serialize_str(v.trim())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub struct Requirement {
|
||||||
|
pub name: String,
|
||||||
|
#[serde(serialize_with = "my_trim")]
|
||||||
|
pub description: String,
|
||||||
|
#[serde(default, skip_serializing_if = "IndexMap::is_empty")]
|
||||||
|
pub depends: IndexMap<String, String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub struct Topic {
|
||||||
|
pub name: String,
|
||||||
|
#[serde(default, skip_serializing_if = "IndexMap::is_empty")]
|
||||||
|
pub requirements: IndexMap<String, Requirement>,
|
||||||
|
#[serde(default, skip_serializing_if = "IndexMap::is_empty")]
|
||||||
|
pub subtopics: IndexMap<String, Topic>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub struct Definition {
|
||||||
|
pub name: String,
|
||||||
|
pub value: String,
|
||||||
|
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||||
|
pub additional_info: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub struct ConfigDefault {
|
||||||
|
pub name: String,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub typ: String,
|
||||||
|
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||||
|
pub valid_values: Vec<String>,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub unit: Option<String>,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub default_value: Option<String>,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub hint: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub struct Project {
|
||||||
|
pub name: String,
|
||||||
|
#[serde(serialize_with = "my_trim")]
|
||||||
|
pub description: String,
|
||||||
|
#[serde(default, skip_serializing_if = "IndexMap::is_empty")]
|
||||||
|
pub topics: IndexMap<String, Topic>,
|
||||||
|
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||||
|
pub definitions: Vec<Definition>,
|
||||||
|
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||||
|
pub config_defaults: Vec<ConfigDefault>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn demo_project() -> Project {
|
||||||
|
Project {
|
||||||
|
name: s!("journal-uploader"),
|
||||||
|
description: s!(r#"
|
||||||
|
The journal-uploader has two main functionalities.
|
||||||
|
- Take a stream of log messages and filter them depending on their severity
|
||||||
|
- Upload journal logs for a specified time when activated through cloud call"#),
|
||||||
|
topics: indexmap! {
|
||||||
|
s!("FEAT-1") => Topic {
|
||||||
|
name: s!("Traced Logging"),
|
||||||
|
subtopics: indexmap! {
|
||||||
|
s!("SUB-1") => Topic {
|
||||||
|
name: s!("File Monitoring"),
|
||||||
|
requirements: indexmap! {
|
||||||
|
s!("REQ-1") => Requirement {
|
||||||
|
name: s!("Continuous Monitoring"),
|
||||||
|
description: s!(r#"The tool must continuously monitor a designated directory."#),
|
||||||
|
depends: indexmap! {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
subtopics: indexmap! {}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
requirements: indexmap! {},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
definitions: vec![
|
||||||
|
Definition {
|
||||||
|
name: s!("Default Journal Directory"),
|
||||||
|
value: s!("/run/log/journal/<machine_id>"),
|
||||||
|
additional_info: vec![s!("Machine ID can be found at /etc/machine-id")],
|
||||||
|
},
|
||||||
|
Definition {
|
||||||
|
name: s!("Default Output Directory"),
|
||||||
|
value: s!("/run/log/filtered-journal"),
|
||||||
|
additional_info: vec![],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
config_defaults: vec![
|
||||||
|
ConfigDefault {
|
||||||
|
name: s!("Journal Directory"),
|
||||||
|
typ: s!("Path"),
|
||||||
|
unit: None,
|
||||||
|
valid_values: vec![],
|
||||||
|
default_value: None,
|
||||||
|
hint: None,
|
||||||
|
},
|
||||||
|
ConfigDefault {
|
||||||
|
name: s!("Output Directory"),
|
||||||
|
typ: s!("Path"),
|
||||||
|
unit: None,
|
||||||
|
valid_values: vec![],
|
||||||
|
default_value: None,
|
||||||
|
hint: None,
|
||||||
|
},
|
||||||
|
ConfigDefault {
|
||||||
|
name: s!("Trigger Priority"),
|
||||||
|
typ: s!("Enum"),
|
||||||
|
unit: None,
|
||||||
|
valid_values: vec![
|
||||||
|
s!("Emergency"),
|
||||||
|
s!("Alert"),
|
||||||
|
s!("Critical"),
|
||||||
|
s!("Error"),
|
||||||
|
s!("Warning"),
|
||||||
|
s!("Notice"),
|
||||||
|
s!("Info"),
|
||||||
|
s!("Debug"),
|
||||||
|
],
|
||||||
|
default_value: Some(s!("Warning")),
|
||||||
|
hint: None,
|
||||||
|
},
|
||||||
|
ConfigDefault {
|
||||||
|
name: s!("Journal Context"),
|
||||||
|
typ: s!("Integer"),
|
||||||
|
unit: Some(s!("Seconds")),
|
||||||
|
valid_values: vec![],
|
||||||
|
default_value: Some(s!("15")),
|
||||||
|
hint: None,
|
||||||
|
},
|
||||||
|
ConfigDefault {
|
||||||
|
name: s!("Max File Size"),
|
||||||
|
typ: s!("Integer"),
|
||||||
|
unit: Some(s!("Bytes")),
|
||||||
|
valid_values: vec![],
|
||||||
|
default_value: Some(s!("8388608")),
|
||||||
|
hint: Some(s!("(8 MB)")),
|
||||||
|
},
|
||||||
|
ConfigDefault {
|
||||||
|
name: s!("Max Directory Size"),
|
||||||
|
typ: s!("Integer"),
|
||||||
|
unit: Some(s!("Bytes")),
|
||||||
|
valid_values: vec![],
|
||||||
|
default_value: Some(s!("75497472")),
|
||||||
|
hint: Some(s!("(72 MB)")),
|
||||||
|
},
|
||||||
|
ConfigDefault {
|
||||||
|
name: s!("File Monitoring Interval"),
|
||||||
|
typ: s!("Integer"),
|
||||||
|
unit: Some(s!("Seconds")),
|
||||||
|
valid_values: vec![],
|
||||||
|
default_value: Some(s!("10")),
|
||||||
|
hint: None,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
use req::*;
|
||||||
|
|
||||||
|
fn main() -> anyhow::Result<()> {
|
||||||
|
let project = demo_project();
|
||||||
|
std::fs::write("req.yml", serde_yaml::to_string(&project)?)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue