format
This commit is contained in:
parent
2997304edc
commit
9108e7d28d
9 changed files with 377 additions and 359 deletions
158
Cargo.lock
generated
158
Cargo.lock
generated
|
@ -13,9 +13,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.57"
|
||||
version = "1.0.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
|
||||
checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61"
|
||||
|
||||
[[package]]
|
||||
name = "asciinema"
|
||||
|
@ -43,7 +43,7 @@ version = "0.2.14"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"hermit-abi 0.1.19",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
@ -68,9 +68,9 @@ checksum = "e0dcbc35f504eb6fc275a6d20e4ebcda18cf50d40ba6fabff8c711fa16cb3b16"
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.73"
|
||||
version = "1.0.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
||||
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
|
@ -95,9 +95,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.21"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e"
|
||||
checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
|
@ -110,9 +110,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.21"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010"
|
||||
checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
|
@ -120,15 +120,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.21"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3"
|
||||
checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.21"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6"
|
||||
checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
|
@ -137,15 +137,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.21"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b"
|
||||
checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.21"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512"
|
||||
checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -154,21 +154,21 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.21"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868"
|
||||
checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.21"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a"
|
||||
checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.21"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
|
||||
checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
|
@ -200,6 +200,15 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
|
@ -211,9 +220,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.1"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
|
||||
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
|
@ -223,15 +232,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.125"
|
||||
version = "0.2.139"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b"
|
||||
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.7"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53"
|
||||
checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
|
@ -297,19 +306,19 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.1"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
|
||||
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"hermit-abi 0.2.6",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.10.0"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
|
||||
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
|
@ -324,9 +333,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.8.5"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
|
||||
checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"instant",
|
||||
|
@ -374,36 +383,36 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.38"
|
||||
version = "1.0.49"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9027b48e9d4c9175fa2218adf3557f91c1137021739951d4932f5f8268ac48aa"
|
||||
checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.18"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
|
||||
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.13"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
|
||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.9"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
|
||||
checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
|
@ -413,15 +422,15 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.137"
|
||||
version = "1.0.152"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
|
||||
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.137"
|
||||
version = "1.0.152"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be"
|
||||
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -430,9 +439,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.81"
|
||||
version = "1.0.91"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c"
|
||||
checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
@ -460,15 +469,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.6"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32"
|
||||
checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.8.0"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
|
||||
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
|
@ -502,13 +514,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.92"
|
||||
version = "1.0.107"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ff7c592601f11445996a06f8ad0c27f094a58857c2f89e97974ab9235b92c52"
|
||||
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -531,18 +543,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.31"
|
||||
version = "1.0.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a"
|
||||
checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.31"
|
||||
version = "1.0.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a"
|
||||
checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -597,22 +609,22 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.9.0"
|
||||
name = "unicode-ident"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99"
|
||||
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.9"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
|
||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
|
|
22
flake.lock
22
flake.lock
|
@ -2,9 +2,7 @@
|
|||
"nodes": {
|
||||
"fenix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"nixpkgs": "nixpkgs",
|
||||
"rust-analyzer-src": "rust-analyzer-src"
|
||||
},
|
||||
"locked": {
|
||||
|
@ -36,6 +34,22 @@
|
|||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1672953546,
|
||||
"narHash": "sha256-oz757DnJ1ITvwyTovuwG3l9cX6j9j6/DH9eH+cXFJmc=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "a518c77148585023ff56022f09c4b2c418a51ef5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1667629849,
|
||||
"narHash": "sha256-P+v+nDOFWicM4wziFK9S/ajF2lc0N2Rg9p6Y35uMoZI=",
|
||||
|
@ -53,7 +67,7 @@
|
|||
"inputs": {
|
||||
"fenix": "fenix",
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
}
|
||||
},
|
||||
"rust-analyzer-src": {
|
||||
|
|
13
flake.nix
13
flake.nix
|
@ -1,8 +1,5 @@
|
|||
{
|
||||
inputs = {
|
||||
fenix.url = "github:nix-community/fenix";
|
||||
fenix.inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
inputs = { fenix.url = "github:nix-community/fenix"; };
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils, fenix }:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
|
@ -12,7 +9,7 @@
|
|||
overlays = [ fenix.overlays.default ];
|
||||
};
|
||||
|
||||
toolchain = pkgs.fenix.default;
|
||||
toolchain = pkgs.fenix.stable;
|
||||
|
||||
flakePkgs = {
|
||||
asciinema = pkgs.callPackage ./. { inherit toolchain; };
|
||||
|
@ -23,9 +20,9 @@
|
|||
|
||||
devShell = pkgs.mkShell {
|
||||
inputsFrom = with packages; [ asciinema ];
|
||||
packages =
|
||||
(with pkgs; [ cargo-watch cargo-deny cargo-edit sqlx-cli sqlite ])
|
||||
++ (with toolchain; [ cargo rustc ]);
|
||||
packages = (with pkgs; [ cargo-watch cargo-deny cargo-edit ])
|
||||
++ (with toolchain; [ cargo rustc rustfmt ]);
|
||||
CARGO_UNSTABLE_SPARSE_REGISTRY = "true";
|
||||
};
|
||||
});
|
||||
}
|
||||
|
|
|
@ -4,66 +4,66 @@ use serde::ser::{Serialize, SerializeSeq, Serializer};
|
|||
|
||||
#[derive(Serialize)]
|
||||
pub struct Header {
|
||||
version: u32,
|
||||
width: u32,
|
||||
height: u32,
|
||||
version: u32,
|
||||
width: u32,
|
||||
height: u32,
|
||||
|
||||
timestamp: Option<u32>,
|
||||
duration: Option<f64>,
|
||||
idle_time_limit: Option<f64>,
|
||||
command: Option<String>,
|
||||
title: Option<String>,
|
||||
env: Option<HashMap<String, String>>,
|
||||
theme: Option<Theme>,
|
||||
timestamp: Option<u32>,
|
||||
duration: Option<f64>,
|
||||
idle_time_limit: Option<f64>,
|
||||
command: Option<String>,
|
||||
title: Option<String>,
|
||||
env: Option<HashMap<String, String>>,
|
||||
theme: Option<Theme>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Theme {
|
||||
fg: String,
|
||||
bg: String,
|
||||
palette: String,
|
||||
fg: String,
|
||||
bg: String,
|
||||
palette: String,
|
||||
}
|
||||
|
||||
pub struct Event<'a>(pub f64, pub EventKind<'a>);
|
||||
|
||||
pub enum EventKind<'a> {
|
||||
Output(&'a [u8]),
|
||||
Input(&'a [u8]),
|
||||
Output(&'a [u8]),
|
||||
Input(&'a [u8]),
|
||||
}
|
||||
|
||||
impl<'a> Serialize for Event<'a> {
|
||||
fn serialize<S: Serializer>(
|
||||
&self,
|
||||
s: S,
|
||||
) -> std::result::Result<S::Ok, S::Error> {
|
||||
let mut seq = s.serialize_seq(Some(3))?;
|
||||
seq.serialize_element(&self.0)?;
|
||||
match &self.1 {
|
||||
EventKind::Output(s) => {
|
||||
seq.serialize_element("o")?;
|
||||
seq.serialize_element(std::str::from_utf8(s).unwrap())?;
|
||||
}
|
||||
EventKind::Input(s) => {
|
||||
seq.serialize_element("i")?;
|
||||
seq.serialize_element(std::str::from_utf8(s).unwrap())?;
|
||||
}
|
||||
}
|
||||
seq.end()
|
||||
fn serialize<S: Serializer>(
|
||||
&self,
|
||||
s: S,
|
||||
) -> std::result::Result<S::Ok, S::Error> {
|
||||
let mut seq = s.serialize_seq(Some(3))?;
|
||||
seq.serialize_element(&self.0)?;
|
||||
match &self.1 {
|
||||
EventKind::Output(s) => {
|
||||
seq.serialize_element("o")?;
|
||||
seq.serialize_element(std::str::from_utf8(s).unwrap())?;
|
||||
}
|
||||
EventKind::Input(s) => {
|
||||
seq.serialize_element("i")?;
|
||||
seq.serialize_element(std::str::from_utf8(s).unwrap())?;
|
||||
}
|
||||
}
|
||||
seq.end()
|
||||
}
|
||||
}
|
||||
|
||||
fn build_header(width: u32, height: u32) -> Header {
|
||||
Header {
|
||||
version: 2,
|
||||
width,
|
||||
height,
|
||||
Header {
|
||||
version: 2,
|
||||
width,
|
||||
height,
|
||||
|
||||
timestamp: None,
|
||||
duration: None,
|
||||
idle_time_limit: None,
|
||||
command: None,
|
||||
title: None,
|
||||
env: None,
|
||||
theme: None,
|
||||
}
|
||||
timestamp: None,
|
||||
duration: None,
|
||||
idle_time_limit: None,
|
||||
command: None,
|
||||
title: None,
|
||||
env: None,
|
||||
theme: None,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,15 +2,15 @@ pub type Result<T, E = Error> = std::result::Result<T, E>;
|
|||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum Error {
|
||||
#[error("generic nix error: {0}")]
|
||||
Nix(#[from] nix::Error),
|
||||
#[error("generic nix error: {0}")]
|
||||
Nix(#[from] nix::Error),
|
||||
|
||||
#[error("write(3) error (fd={1}, data={2:?}): {0}")]
|
||||
NixWrite(nix::Error, i32, Vec<u8>),
|
||||
#[error("write(3) error (fd={1}, data={2:?}): {0}")]
|
||||
NixWrite(nix::Error, i32, Vec<u8>),
|
||||
|
||||
#[error("generic io error: {0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
#[error("generic io error: {0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
|
||||
#[error("generic serde_json error: {0}")]
|
||||
SerdeJson(#[from] serde_json::Error),
|
||||
#[error("generic serde_json error: {0}")]
|
||||
SerdeJson(#[from] serde_json::Error),
|
||||
}
|
||||
|
|
22
src/main.rs
22
src/main.rs
|
@ -19,22 +19,22 @@ use crate::writer::FileWriter;
|
|||
|
||||
#[derive(StructOpt)]
|
||||
enum Command {
|
||||
/// Record terminal session.
|
||||
#[structopt(name = "rec")]
|
||||
Record,
|
||||
/// Record terminal session.
|
||||
#[structopt(name = "rec")]
|
||||
Record,
|
||||
}
|
||||
|
||||
fn record() -> Result<()> {
|
||||
let file = File::create("output.cast")?;
|
||||
pty::record(&["sh", "-c", "/usr/bin/zsh"], FileWriter::new(file))?;
|
||||
Ok(())
|
||||
let file = File::create("output.cast")?;
|
||||
pty::record(&["sh", "-c", "/usr/bin/zsh"], FileWriter::new(file))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
match Command::from_args() {
|
||||
Command::Record => {
|
||||
record()?;
|
||||
}
|
||||
match Command::from_args() {
|
||||
Command::Record => {
|
||||
record()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
333
src/pty.rs
333
src/pty.rs
|
@ -5,15 +5,15 @@ use std::os::unix::io::RawFd;
|
|||
use std::time::Instant;
|
||||
|
||||
use nix::{
|
||||
fcntl::{fcntl, FcntlArg, OFlag},
|
||||
ioctl_write_buf,
|
||||
pty::{forkpty, Winsize},
|
||||
sys::{
|
||||
select::{select, FdSet},
|
||||
termios::{tcsetattr, SetArg, Termios},
|
||||
wait::waitpid,
|
||||
},
|
||||
unistd::{execvpe, isatty, pipe, read, write, ForkResult},
|
||||
fcntl::{fcntl, FcntlArg, OFlag},
|
||||
ioctl_write_buf,
|
||||
pty::{forkpty, Winsize},
|
||||
sys::{
|
||||
select::{select, FdSet},
|
||||
termios::{tcsetattr, SetArg, Termios},
|
||||
wait::waitpid,
|
||||
},
|
||||
unistd::{execvpe, isatty, pipe, read, write, ForkResult},
|
||||
};
|
||||
use signal_hook::SigId;
|
||||
|
||||
|
@ -24,181 +24,180 @@ const STDIN_FILENO: RawFd = 0;
|
|||
const STDOUT_FILENO: RawFd = 1;
|
||||
|
||||
pub fn record(args: &[&str], writer: impl Writer + Send) -> Result<()> {
|
||||
let forkpty_result = forkpty(None, None)?;
|
||||
let master_fd = forkpty_result.master;
|
||||
let start_time = Instant::now();
|
||||
let forkpty_result = forkpty(None, None)?;
|
||||
let master_fd = forkpty_result.master;
|
||||
let start_time = Instant::now();
|
||||
|
||||
let set_pty_size = || -> Result<()> {
|
||||
ioctl_write_buf!(helper_write, libc::TIOCGWINSZ, 104, Winsize);
|
||||
let winsize = Winsize {
|
||||
ws_row: 24,
|
||||
ws_col: 80,
|
||||
ws_xpixel: 0,
|
||||
ws_ypixel: 0,
|
||||
};
|
||||
if isatty(STDOUT_FILENO)? {}
|
||||
unsafe { helper_write(master_fd, &[winsize]) }?;
|
||||
Ok(())
|
||||
let _set_pty_size = || -> Result<()> {
|
||||
ioctl_write_buf!(helper_write, libc::TIOCGWINSZ, 104, Winsize);
|
||||
let winsize = Winsize {
|
||||
ws_row: 24,
|
||||
ws_col: 80,
|
||||
ws_xpixel: 0,
|
||||
ws_ypixel: 0,
|
||||
};
|
||||
|
||||
let write_stdout = |data: &[u8]| -> Result<()> {
|
||||
write(STDOUT_FILENO, &data)?;
|
||||
Ok(())
|
||||
};
|
||||
|
||||
let mut master_writer = writer.clone();
|
||||
let mut handle_master_read = move |data: &[u8]| -> Result<()> {
|
||||
let elapsed = (Instant::now() - start_time).as_secs_f64();
|
||||
master_writer.write_stdout(elapsed, data)?;
|
||||
write_stdout(data)?;
|
||||
Ok(())
|
||||
};
|
||||
|
||||
let write_master = |data: &[u8]| -> Result<()> {
|
||||
let mut offset = 0;
|
||||
while offset < data.len() {
|
||||
let len = write(master_fd, data).map_err(|err| {
|
||||
Error::NixWrite(err, master_fd, data.to_vec())
|
||||
})?;
|
||||
offset += len;
|
||||
}
|
||||
Ok(())
|
||||
};
|
||||
|
||||
let mut stdin_writer = writer.clone();
|
||||
let mut handle_stdin_read = |data: &[u8]| -> Result<()> {
|
||||
write_master(data)?;
|
||||
let elapsed = (Instant::now() - start_time).as_secs_f64();
|
||||
stdin_writer.write_stdin(elapsed, data)?;
|
||||
Ok(())
|
||||
};
|
||||
|
||||
let mut copy = |signal_fd: RawFd| -> Result<()> {
|
||||
let mut fdset = FdSet::new();
|
||||
let mut buf = [0; 1024];
|
||||
|
||||
loop {
|
||||
fdset.clear();
|
||||
fdset.insert(master_fd);
|
||||
fdset.insert(STDIN_FILENO);
|
||||
fdset.insert(signal_fd);
|
||||
|
||||
select(None, &mut fdset, None, None, None)?;
|
||||
|
||||
if fdset.contains(master_fd) {
|
||||
let len = read(master_fd, &mut buf)?;
|
||||
if len == 0 {
|
||||
fdset.remove(master_fd);
|
||||
} else {
|
||||
handle_master_read(&buf[..len])?;
|
||||
}
|
||||
} else if fdset.contains(STDIN_FILENO) {
|
||||
let len = read(STDIN_FILENO, &mut buf)?;
|
||||
if len == 0 {
|
||||
fdset.remove(STDIN_FILENO);
|
||||
} else {
|
||||
handle_stdin_read(&buf[..len])?;
|
||||
}
|
||||
} else if fdset.contains(signal_fd) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let child_pid = match forkpty_result.fork_result {
|
||||
ForkResult::Parent { child } => child,
|
||||
ForkResult::Child => {
|
||||
let cstr_args: Vec<_> = args
|
||||
.into_iter()
|
||||
.map(|s| CString::new(*s).unwrap())
|
||||
.collect();
|
||||
let args: Vec<_> = cstr_args.iter().map(|s| s.as_ref()).collect();
|
||||
let cstr_env: Vec<_> = env::vars()
|
||||
.map(|(k, v)| CString::new(format!("{}={}", k, v)).unwrap())
|
||||
.collect();
|
||||
let env: Vec<_> = cstr_env.iter().map(|s| s.as_ref()).collect();
|
||||
execvpe(&args[0], &args, &env)?;
|
||||
unreachable!();
|
||||
}
|
||||
};
|
||||
|
||||
let (pipe_r, pipe_w) = pipe()?;
|
||||
let mut flags = fcntl(pipe_w, FcntlArg::F_GETFL)?;
|
||||
flags |= libc::O_NONBLOCK;
|
||||
fcntl(pipe_w, FcntlArg::F_SETFL(OFlag::from_bits(flags).unwrap()))?;
|
||||
|
||||
let old_handlers = set_signals(
|
||||
[
|
||||
signal_hook::SIGWINCH,
|
||||
signal_hook::SIGCHLD,
|
||||
signal_hook::SIGHUP,
|
||||
signal_hook::SIGTERM,
|
||||
signal_hook::SIGQUIT,
|
||||
]
|
||||
.iter()
|
||||
.map(|sig| (*sig, move || eprintln!("HIT SIGNAL {:?}", *sig))),
|
||||
)?;
|
||||
|
||||
// set_pty_size()?;
|
||||
|
||||
{
|
||||
let _term = RawTerm::init(STDIN_FILENO)?;
|
||||
copy(pipe_r)?;
|
||||
}
|
||||
unset_signals(old_handlers)?;
|
||||
|
||||
waitpid(child_pid, None)?;
|
||||
|
||||
if isatty(STDOUT_FILENO)? {}
|
||||
unsafe { helper_write(master_fd, &[winsize]) }?;
|
||||
Ok(())
|
||||
};
|
||||
|
||||
let write_stdout = |data: &[u8]| -> Result<()> {
|
||||
write(STDOUT_FILENO, &data)?;
|
||||
Ok(())
|
||||
};
|
||||
|
||||
let mut master_writer = writer.clone();
|
||||
let mut handle_master_read = move |data: &[u8]| -> Result<()> {
|
||||
let elapsed = (Instant::now() - start_time).as_secs_f64();
|
||||
master_writer.write_stdout(elapsed, data)?;
|
||||
write_stdout(data)?;
|
||||
Ok(())
|
||||
};
|
||||
|
||||
let write_master = |data: &[u8]| -> Result<()> {
|
||||
let mut offset = 0;
|
||||
while offset < data.len() {
|
||||
let len = write(master_fd, data)
|
||||
.map_err(|err| Error::NixWrite(err, master_fd, data.to_vec()))?;
|
||||
offset += len;
|
||||
}
|
||||
Ok(())
|
||||
};
|
||||
|
||||
let mut stdin_writer = writer.clone();
|
||||
let mut handle_stdin_read = |data: &[u8]| -> Result<()> {
|
||||
write_master(data)?;
|
||||
let elapsed = (Instant::now() - start_time).as_secs_f64();
|
||||
stdin_writer.write_stdin(elapsed, data)?;
|
||||
Ok(())
|
||||
};
|
||||
|
||||
let mut copy = |signal_fd: RawFd| -> Result<()> {
|
||||
let mut fdset = FdSet::new();
|
||||
let mut buf = [0; 1024];
|
||||
|
||||
loop {
|
||||
fdset.clear();
|
||||
fdset.insert(master_fd);
|
||||
fdset.insert(STDIN_FILENO);
|
||||
fdset.insert(signal_fd);
|
||||
|
||||
select(None, &mut fdset, None, None, None)?;
|
||||
|
||||
if fdset.contains(master_fd) {
|
||||
let len = read(master_fd, &mut buf)?;
|
||||
if len == 0 {
|
||||
fdset.remove(master_fd);
|
||||
} else {
|
||||
handle_master_read(&buf[..len])?;
|
||||
}
|
||||
} else if fdset.contains(STDIN_FILENO) {
|
||||
let len = read(STDIN_FILENO, &mut buf)?;
|
||||
if len == 0 {
|
||||
fdset.remove(STDIN_FILENO);
|
||||
} else {
|
||||
handle_stdin_read(&buf[..len])?;
|
||||
}
|
||||
} else if fdset.contains(signal_fd) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let child_pid = match forkpty_result.fork_result {
|
||||
ForkResult::Parent { child } => child,
|
||||
ForkResult::Child => {
|
||||
let cstr_args: Vec<_> = args
|
||||
.into_iter()
|
||||
.map(|s| CString::new(*s).unwrap())
|
||||
.collect();
|
||||
let args: Vec<_> = cstr_args.iter().map(|s| s.as_ref()).collect();
|
||||
let cstr_env: Vec<_> = env::vars()
|
||||
.map(|(k, v)| CString::new(format!("{}={}", k, v)).unwrap())
|
||||
.collect();
|
||||
let env: Vec<_> = cstr_env.iter().map(|s| s.as_ref()).collect();
|
||||
execvpe(&args[0], &args, &env)?;
|
||||
unreachable!();
|
||||
}
|
||||
};
|
||||
|
||||
let (pipe_r, pipe_w) = pipe()?;
|
||||
let mut flags = fcntl(pipe_w, FcntlArg::F_GETFL)?;
|
||||
flags |= libc::O_NONBLOCK;
|
||||
fcntl(pipe_w, FcntlArg::F_SETFL(OFlag::from_bits(flags).unwrap()))?;
|
||||
|
||||
let old_handlers = set_signals(
|
||||
[
|
||||
signal_hook::SIGWINCH,
|
||||
signal_hook::SIGCHLD,
|
||||
signal_hook::SIGHUP,
|
||||
signal_hook::SIGTERM,
|
||||
signal_hook::SIGQUIT,
|
||||
]
|
||||
.iter()
|
||||
.map(|sig| (*sig, move || eprintln!("HIT SIGNAL {:?}", *sig))),
|
||||
)?;
|
||||
|
||||
// set_pty_size()?;
|
||||
|
||||
{
|
||||
let _term = RawTerm::init(STDIN_FILENO)?;
|
||||
copy(pipe_r)?;
|
||||
}
|
||||
unset_signals(old_handlers)?;
|
||||
|
||||
waitpid(child_pid, None)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_signals<I, F>(signals_list: I) -> Result<Vec<SigId>, io::Error>
|
||||
where
|
||||
I: Iterator<Item = (i32, F)>,
|
||||
F: Fn() + Sync + Send + 'static,
|
||||
I: Iterator<Item = (i32, F)>,
|
||||
F: Fn() + Sync + Send + 'static,
|
||||
{
|
||||
let mut old_handlers = Vec::new();
|
||||
for (sig, handler) in signals_list {
|
||||
old_handlers.push(unsafe { signal_hook::register(sig, handler) }?);
|
||||
}
|
||||
Ok(old_handlers)
|
||||
let mut old_handlers = Vec::new();
|
||||
for (sig, handler) in signals_list {
|
||||
old_handlers.push(unsafe { signal_hook::register(sig, handler) }?);
|
||||
}
|
||||
Ok(old_handlers)
|
||||
}
|
||||
|
||||
fn unset_signals(handlers_list: Vec<SigId>) -> Result<(), io::Error> {
|
||||
for handler in handlers_list {
|
||||
signal_hook::unregister(handler);
|
||||
}
|
||||
Ok(())
|
||||
for handler in handlers_list {
|
||||
signal_hook::unregister(handler);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
struct RawTerm(RawFd, Termios);
|
||||
|
||||
impl RawTerm {
|
||||
pub fn init(fd: RawFd) -> Result<Self> {
|
||||
use nix::sys::termios::*;
|
||||
let saved_mode = tcgetattr(fd)?;
|
||||
let mut mode = saved_mode.clone();
|
||||
mode.input_flags &= !(InputFlags::BRKINT
|
||||
| InputFlags::ICRNL
|
||||
| InputFlags::INPCK
|
||||
| InputFlags::ISTRIP
|
||||
| InputFlags::IXON);
|
||||
mode.output_flags &= !OutputFlags::OPOST;
|
||||
mode.control_flags &= !(ControlFlags::CSIZE | ControlFlags::PARENB);
|
||||
mode.control_flags |= ControlFlags::CS8;
|
||||
mode.local_flags &= !(LocalFlags::ECHO
|
||||
| LocalFlags::ICANON
|
||||
| LocalFlags::IEXTEN
|
||||
| LocalFlags::ISIG);
|
||||
mode.control_chars[libc::VMIN] = 1;
|
||||
mode.control_chars[libc::VTIME] = 0;
|
||||
tcsetattr(fd, SetArg::TCSAFLUSH, &mode)?;
|
||||
Ok(RawTerm(fd, saved_mode))
|
||||
}
|
||||
pub fn init(fd: RawFd) -> Result<Self> {
|
||||
use nix::sys::termios::*;
|
||||
let saved_mode = tcgetattr(fd)?;
|
||||
let mut mode = saved_mode.clone();
|
||||
mode.input_flags &= !(InputFlags::BRKINT
|
||||
| InputFlags::ICRNL
|
||||
| InputFlags::INPCK
|
||||
| InputFlags::ISTRIP
|
||||
| InputFlags::IXON);
|
||||
mode.output_flags &= !OutputFlags::OPOST;
|
||||
mode.control_flags &= !(ControlFlags::CSIZE | ControlFlags::PARENB);
|
||||
mode.control_flags |= ControlFlags::CS8;
|
||||
mode.local_flags &= !(LocalFlags::ECHO
|
||||
| LocalFlags::ICANON
|
||||
| LocalFlags::IEXTEN
|
||||
| LocalFlags::ISIG);
|
||||
mode.control_chars[libc::VMIN] = 1;
|
||||
mode.control_chars[libc::VTIME] = 0;
|
||||
tcsetattr(fd, SetArg::TCSAFLUSH, &mode)?;
|
||||
Ok(RawTerm(fd, saved_mode))
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for RawTerm {
|
||||
fn drop(&mut self) {
|
||||
tcsetattr(self.0, SetArg::TCSAFLUSH, &self.1).unwrap();
|
||||
}
|
||||
fn drop(&mut self) {
|
||||
tcsetattr(self.0, SetArg::TCSAFLUSH, &self.1).unwrap();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,34 +1,30 @@
|
|||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::asciicast::Header;
|
||||
use crate::term;
|
||||
|
||||
pub struct RecordOptions {
|
||||
pub path: PathBuf,
|
||||
pub append: Option<bool>,
|
||||
pub command: Option<String>,
|
||||
pub capture_env: Option<Vec<String>>,
|
||||
pub title: Option<String>,
|
||||
pub path: PathBuf,
|
||||
pub append: Option<bool>,
|
||||
pub command: Option<String>,
|
||||
pub capture_env: Option<Vec<String>>,
|
||||
pub title: Option<String>,
|
||||
}
|
||||
|
||||
pub fn record(options: RecordOptions) {
|
||||
let command = options
|
||||
.command
|
||||
.unwrap_or_else(|| env::var("SHELL").unwrap_or_else(|_| "sh".to_string()));
|
||||
let _command = options
|
||||
.command
|
||||
.unwrap_or_else(|| env::var("SHELL").unwrap_or_else(|_| "sh".to_string()));
|
||||
|
||||
let command_env = env::vars();
|
||||
let _command_env = env::vars();
|
||||
|
||||
// let header_env = HashMap::new();
|
||||
// let header_env = HashMap::new();
|
||||
|
||||
// let (width, height) = term::get_size();
|
||||
// let (width, height) = term::get_size();
|
||||
|
||||
// let header = Header {
|
||||
// version: 2,
|
||||
// width,
|
||||
// height,
|
||||
// let header = Header {
|
||||
// version: 2,
|
||||
// width,
|
||||
// height,
|
||||
|
||||
// title: options.title,
|
||||
// };
|
||||
// title: options.title,
|
||||
// };
|
||||
}
|
||||
|
|
|
@ -8,38 +8,38 @@ use crate::asciicast::{Event, EventKind};
|
|||
use crate::errors::Result;
|
||||
|
||||
pub trait Writer: Clone {
|
||||
fn write_line(&mut self, line: String) -> Result<(), io::Error>;
|
||||
fn write_line(&mut self, line: String) -> Result<(), io::Error>;
|
||||
|
||||
fn write_stdin(&mut self, time: f64, data: &[u8]) -> Result<()> {
|
||||
let output = EventKind::Input(data);
|
||||
let event = Event(time, output);
|
||||
self.write_line(serde_json::to_string(&event)?)?;
|
||||
Ok(())
|
||||
}
|
||||
fn write_stdin(&mut self, time: f64, data: &[u8]) -> Result<()> {
|
||||
let output = EventKind::Input(data);
|
||||
let event = Event(time, output);
|
||||
self.write_line(serde_json::to_string(&event)?)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_stdout(&mut self, time: f64, data: &[u8]) -> Result<()> {
|
||||
let output = EventKind::Output(data);
|
||||
let event = Event(time, output);
|
||||
self.write_line(serde_json::to_string(&event)?)?;
|
||||
Ok(())
|
||||
}
|
||||
fn write_stdout(&mut self, time: f64, data: &[u8]) -> Result<()> {
|
||||
let output = EventKind::Output(data);
|
||||
let event = Event(time, output);
|
||||
self.write_line(serde_json::to_string(&event)?)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FileWriter(Arc<Mutex<File>>);
|
||||
|
||||
impl FileWriter {
|
||||
pub fn new(file: File) -> Self {
|
||||
FileWriter(Arc::new(Mutex::new(file)))
|
||||
}
|
||||
pub fn new(file: File) -> Self {
|
||||
FileWriter(Arc::new(Mutex::new(file)))
|
||||
}
|
||||
}
|
||||
|
||||
impl Writer for FileWriter {
|
||||
fn write_line(&mut self, line: String) -> Result<(), io::Error> {
|
||||
let mut writer = self.0.lock();
|
||||
writer.write_all(line.as_bytes())?;
|
||||
writer.write(b"\n")?;
|
||||
writer.flush()?;
|
||||
Ok(())
|
||||
}
|
||||
fn write_line(&mut self, line: String) -> Result<(), io::Error> {
|
||||
let mut writer = self.0.lock();
|
||||
writer.write_all(line.as_bytes())?;
|
||||
writer.write(b"\n")?;
|
||||
writer.flush()?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue