132 Commits

Author SHA1 Message Date
oysteikt 291aa6877c WIP 2025-12-08 18:43:44 +09:00
oysteikt c48a8adcdc .gitea/workflows: run on debian-latest-slim
Build and test / build (push) Failing after 19s
Build and test / check (push) Failing after 19s
Build and test / test (push) Failing after 23s
Build and test / docs (push) Failing after 15s
2025-12-08 18:43:29 +09:00
oysteikt 1f1e7fbb53 .gitea/workflows: update actions/checkout: v4 -> v6 2025-12-08 18:43:24 +09:00
oysteikt 7ec268094d commands: store SubtypeParserError expected type as &str
Build and test / check (push) Successful in 58s
Build and test / build (push) Successful in 1m9s
Build and test / docs (push) Successful in 1m11s
Build and test / test (push) Successful in 2m26s
2025-12-08 17:48:44 +09:00
oysteikt afa690366f commands: use new error variants for a few more commands
Build and test / check (push) Successful in 1m2s
Build and test / build (push) Successful in 1m9s
Build and test / docs (push) Successful in 1m25s
Build and test / test (push) Successful in 1m38s
2025-12-08 17:40:07 +09:00
oysteikt 02ba7f2684 lib: fix doccomment url rendering
Build and test / build (push) Successful in 1m4s
Build and test / check (push) Successful in 1m23s
Build and test / test (push) Successful in 1m52s
Build and test / docs (push) Successful in 1m16s
2025-12-08 16:27:55 +09:00
oysteikt 44903f2ce0 commands: add request parser error variant for keyword without value
Build and test / check (push) Successful in 1m5s
Build and test / build (push) Successful in 1m6s
Build and test / docs (push) Has been cancelled
Build and test / test (push) Has been cancelled
2025-12-08 16:25:43 +09:00
oysteikt 9f50d61ad5 commands: clearly define how arguments are counted in request error 2025-12-08 16:25:40 +09:00
oysteikt 788a01ce83 Clean up misc. module doccomments
Build and test / build (push) Successful in 1m10s
Build and test / check (push) Successful in 1m0s
Build and test / test (push) Successful in 2m15s
Build and test / docs (push) Successful in 1m19s
2025-12-08 16:16:34 +09:00
oysteikt f5451b6c2f filter: document misc
Build and test / check (push) Successful in 57s
Build and test / build (push) Successful in 1m10s
Build and test / docs (push) Successful in 1m13s
Build and test / test (push) Successful in 2m23s
2025-12-08 16:09:55 +09:00
oysteikt 2de18cdbdb .gitea/workflows: don't error on clippy warnings
Build and test / check (push) Successful in 1m4s
Build and test / build (push) Successful in 1m29s
Build and test / test (push) Successful in 1m48s
Build and test / docs (push) Successful in 2m13s
2025-12-08 15:59:10 +09:00
oysteikt 23bfd0c4a7 .gitea/workflows: don't run with all features
Build and test / build (push) Successful in 1m6s
Build and test / check (push) Failing after 1m23s
Build and test / test (push) Successful in 1m54s
Build and test / docs (push) Successful in 1m23s
2025-12-08 15:57:40 +09:00
oysteikt 3342293bf2 commands: use new error variants for various commands
Build and test / build (push) Failing after 1m1s
Build and test / check (push) Failing after 1m25s
Build and test / test (push) Failing after 1m25s
Build and test / docs (push) Failing after 1m0s
2025-12-08 15:54:37 +09:00
oysteikt 2b3ab7389d Preallocate a few more response parsers
Build and test / check (push) Failing after 58s
Build and test / build (push) Failing after 1m23s
Build and test / test (push) Failing after 1m28s
Build and test / docs (push) Failing after 1m1s
2025-12-08 14:27:42 +09:00
oysteikt f80d36e962 commands: add and fix variants for RequestParserError
Build and test / build (push) Failing after 1m0s
Build and test / check (push) Failing after 1m21s
Build and test / test (push) Failing after 1m18s
Build and test / docs (push) Failing after 1m48s
2025-12-08 14:02:39 +09:00
oysteikt 86edd4c5b3 filter: flatten module
Build and test / check (push) Failing after 1m2s
Build and test / test (push) Failing after 1m17s
Build and test / build (push) Failing after 1m23s
Build and test / docs (push) Failing after 1m9s
2025-12-08 13:32:18 +09:00
oysteikt a7a8ceedeb cargo fmt + clippy
Build and test / build (push) Failing after 1m5s
Build and test / check (push) Failing after 1m17s
Build and test / test (push) Failing after 1m21s
Build and test / docs (push) Failing after 1m13s
2025-12-08 13:28:45 +09:00
oysteikt 7ce0d68021 commands: extend parser errors 2025-12-08 13:28:17 +09:00
oysteikt b5cb4677ee Remove a few unused type aliases
Build and test / check (push) Failing after 59s
Build and test / build (push) Failing after 1m1s
Build and test / test (push) Failing after 1m26s
Build and test / docs (push) Failing after 1m49s
2025-12-08 13:11:09 +09:00
oysteikt 38faf99de7 *_tokenizer: add module doccomment 2025-12-08 13:10:31 +09:00
oysteikt 69f252bad8 commands: force external users to interact with requests and responses through Command trait
Build and test / check (push) Failing after 42s
Build and test / build (push) Failing after 1m0s
Build and test / docs (push) Failing after 1m7s
Build and test / test (push) Failing after 1m45s
2025-12-08 13:07:11 +09:00
oysteikt c177c089a3 commands: add command executor directly on Command trait
Build and test / check (push) Failing after 41s
Build and test / build (push) Failing after 59s
Build and test / test (push) Has been cancelled
Build and test / docs (push) Has been cancelled
2025-12-08 13:05:30 +09:00
oysteikt d964e7857b examples/mpd-client: add some code
Build and test / docs (push) Has been cancelled
Build and test / test (push) Has been cancelled
Build and test / build (push) Has been cancelled
Build and test / check (push) Has been cancelled
2025-12-08 13:00:46 +09:00
oysteikt 8430592bee commands: strip lifetimes 2025-12-08 12:30:19 +09:00
oysteikt 78cfc09d60 commands: add newline at end of all command serializers 2025-12-08 12:13:05 +09:00
oysteikt a7b764ad0f client: init
Build and test / check (push) Failing after 59s
Build and test / build (push) Failing after 1m7s
Build and test / test (push) Failing after 1m50s
Build and test / docs (push) Failing after 1m5s
2025-12-08 05:32:49 +09:00
oysteikt f3e6fe13df MpdError: impl thiserror 2025-12-08 05:31:43 +09:00
oysteikt 4f8f5db620 make ResponseParserError self-contained, impl thiserror 2025-12-08 05:31:13 +09:00
oysteikt 1e39640508 common/types: flatten to types
Build and test / check (push) Failing after 47s
Build and test / build (push) Failing after 1m3s
Build and test / docs (push) Failing after 1m1s
Build and test / test (push) Failing after 1m48s
2025-12-08 04:14:32 +09:00
oysteikt b388bc727b commands: document module 2025-12-08 04:07:20 +09:00
oysteikt 9f859e1df1 response: add some notes about the errors
Build and test / build (push) Successful in 1m7s
Build and test / check (push) Failing after 1m8s
Build and test / docs (push) Successful in 1m11s
Build and test / test (push) Successful in 2m20s
2025-12-08 01:46:14 +09:00
oysteikt 4bb5702eba cargo clippy
Build and test / build (push) Successful in 1m3s
Build and test / check (push) Failing after 1m24s
Build and test / test (push) Successful in 1m50s
Build and test / docs (push) Successful in 1m14s
2025-12-08 01:08:58 +09:00
oysteikt 955fdbcff1 commands/stickernamestypes: add missing derive for response 2025-12-08 01:05:24 +09:00
oysteikt 322c8c8fc3 commands/listplaylist: add note about format
Build and test / build (push) Successful in 1m10s
Build and test / check (push) Failing after 1m25s
Build and test / test (push) Successful in 1m36s
Build and test / docs (push) Successful in 1m17s
2025-12-08 01:03:23 +09:00
oysteikt 93afaf1bde commands/seekcur: fix parser 2025-12-08 01:03:11 +09:00
oysteikt c915c67f08 commands: fix request enum conversion for unmount 2025-12-08 00:52:27 +09:00
oysteikt 813ffac614 flake.lock: bump inputs
Build and test / check (push) Failing after 58s
Build and test / build (push) Successful in 1m29s
Build and test / test (push) Successful in 1m49s
Build and test / docs (push) Successful in 1m12s
2025-12-08 00:45:53 +09:00
oysteikt b0bc2752cc commands: add response types for multiple commands
Build and test / build (push) Successful in 1m3s
Build and test / test (push) Has been cancelled
Build and test / docs (push) Has been cancelled
Build and test / check (push) Has been cancelled
2025-12-08 00:44:37 +09:00
oysteikt 07e9161137 commands/currentsong: implement response parser
Build and test / build (push) Successful in 1m6s
Build and test / check (push) Failing after 1m23s
Build and test / test (push) Successful in 1m38s
Build and test / docs (push) Successful in 2m4s
2025-12-08 00:29:00 +09:00
oysteikt f2977f1ba9 commands/listplaylistinfo: fix response type 2025-12-08 00:28:38 +09:00
oysteikt b0b4134829 commands: split Command trait into req + res parts
Build and test / check (push) Failing after 1m2s
Build and test / build (push) Successful in 1m8s
Build and test / test (push) Successful in 2m23s
Build and test / docs (push) Successful in 1m24s
2025-12-08 00:07:37 +09:00
oysteikt c1dbdd4644 cargo fmt
Build and test / check (push) Failing after 58s
Build and test / build (push) Successful in 1m6s
Build and test / docs (push) Successful in 1m10s
Build and test / test (push) Successful in 2m19s
2025-12-07 21:40:50 +09:00
oysteikt 64c94d6e89 commands/listplaylistinfo: add response type
Build and test / check (push) Failing after 44s
Build and test / build (push) Successful in 1m0s
Build and test / docs (push) Successful in 1m25s
Build and test / test (push) Successful in 3m0s
2025-12-07 21:33:01 +09:00
oysteikt 4d11df5ad1 commands: implement all database selection responses 2025-12-07 21:24:49 +09:00
oysteikt 0cacbe2229 common/types: add db selection print types 2025-12-07 21:22:35 +09:00
oysteikt 7bbe1c4ced types/tag: make orderable 2025-12-07 21:22:34 +09:00
oysteikt 83918fd432 commands/listplaylists: implement 2025-12-07 21:22:33 +09:00
oysteikt 07e1c76aa9 commands: parse to Self::Request
Build and test / check (push) Failing after 43s
Build and test / build (push) Successful in 1m2s
Build and test / docs (push) Successful in 1m12s
Build and test / test (push) Successful in 1m44s
2025-12-05 22:00:11 +09:00
oysteikt d84e653db2 filter: export all types from inner module 2025-12-05 21:00:01 +09:00
oysteikt 7834bbd956 common: don't expose types directly 2025-12-05 20:59:19 +09:00
oysteikt 249ffb2a36 commands: add docs for Command trait
Build and test / check (push) Failing after 58s
Build and test / build (push) Successful in 1m10s
Build and test / docs (push) Successful in 1m10s
Build and test / test (push) Successful in 2m53s
2025-11-25 05:28:58 +09:00
oysteikt fdd4880d05 common/types: add better alias for MountPath 2025-11-25 05:28:19 +09:00
oysteikt 9ca6544057 common/types: add better alias for AudioOutputId 2025-11-25 05:28:19 +09:00
oysteikt e5f70ca87a common/types: add type for ChannelName 2025-11-25 05:28:19 +09:00
oysteikt b03f60c985 common/types: add better alias for PlaylistVersion 2025-11-25 05:28:19 +09:00
oysteikt b22016e970 common/types: add type for Sort 2025-11-25 03:56:01 +09:00
oysteikt 65c7798d01 response_tokenizer: rewrite
This commit contains a rewrite of the response tokenizer, which
introduces lazy parsing of the response, handling of binary data, some
tests, as well as just generally more robustness against errors.
2025-11-24 23:53:03 +09:00
oysteikt 5188809327 commands: fix request de/serialization for list 2025-11-24 22:00:42 +09:00
oysteikt a4276a2caa commands: remove some fixed TODOs 2025-11-24 21:59:42 +09:00
oysteikt 7b27a650a1 commands: split response tokenizer into separate file 2025-11-24 19:28:28 +09:00
oysteikt 062dbcafb8 filter: implement basic parser 2025-11-24 19:25:01 +09:00
oysteikt 57a6b0a3ee common/types: case insensitive tags 2025-11-24 19:25:00 +09:00
oysteikt b5fbaadca2 Implement a proper request tokenizer 2025-11-24 19:25:00 +09:00
oysteikt 3bd7aaaad2 WIP: serialize requests 2025-11-21 18:50:58 +09:00
oysteikt 8aba3d8859 filter: implement fmt::Display 2025-11-21 18:50:58 +09:00
oysteikt e4ece7d6b2 common/types: implement serialization helpers for Tag 2025-11-21 18:50:58 +09:00
oysteikt f07f90aee5 common/types: implement fmt::Display 2025-11-21 18:50:58 +09:00
oysteikt 6e2aa2ba65 Cargo.toml: bump deps 2025-11-21 16:15:16 +09:00
oysteikt 1ef8ef669a flake.lock: bump 2025-11-21 16:14:13 +09:00
oysteikt c6a123a6e1 commands: implement response parser for lsinfo 2025-11-21 16:13:09 +09:00
oysteikt 06e24f0ce0 cargo fmt + clippy 2025-11-21 16:04:46 +09:00
oysteikt da31ab75e2 filter: add unit tests 2025-11-21 15:49:27 +09:00
oysteikt d09ca013d5 commands: implement response parser for tagtypes available 2025-11-21 15:16:30 +09:00
oysteikt 10913fd48c commands: implement response parser for protocol 2025-11-21 15:14:43 +09:00
oysteikt 73ddb6d498 commands: implement response parser for protocol available 2025-11-21 15:12:21 +09:00
oysteikt ede28623ef commands: return runtime errors on invalid property names 2025-11-21 15:07:50 +09:00
oysteikt 130fe49597 commands: create result struct for readmessages 2025-11-21 14:55:57 +09:00
oysteikt 4a1df97ad6 commands: precalculate capacity and use iterators 2025-11-21 14:44:17 +09:00
oysteikt 7a966051d5 commands: make better use of expect_property_type! 2025-11-21 14:38:09 +09:00
oysteikt 7dc3d7f9cf commands: implement response parser for listmounts 2025-11-21 14:32:06 +09:00
oysteikt 2b1e99445a commands: implement common traits for responses 2025-11-21 14:18:44 +09:00
oysteikt e932b62195 commands: implement response parser for decoders 2025-11-21 14:14:25 +09:00
oysteikt 49f440770e commands: implement response parser for listneighbors 2025-11-21 14:04:12 +09:00
oysteikt 153ae9520f commands: implement response parser for outputs 2025-11-21 13:55:10 +09:00
oysteikt 424c530d5d common/types: add debug assertions for range orders 2025-10-13 15:35:56 +09:00
oysteikt a637f24e66 flake.lock: bump, Cargo.toml: update inputs 2025-10-12 23:01:17 +09:00
oysteikt 1d693b7b2a commands: fix clippy warnings about confusing elided lifetimes 2025-10-12 22:59:50 +09:00
oysteikt 484b1fb68d flake.lock: bump, Cargo.toml: update inputs 2025-09-20 18:05:21 +02:00
oysteikt 2fa58533ba .gitignore: ignore Cargo.lock
This is okay because this is a library
2025-09-20 18:03:35 +02:00
oysteikt 088665c9ff flake.lock: bump
Build and test / build (push) Successful in 45s
Build and test / check (push) Failing after 46s
Build and test / test (push) Successful in 1m11s
Build and test / docs (push) Successful in 1m37s
2025-08-03 05:01:37 +02:00
oysteikt 3e2e3fdc68 .gitea/workflows: update gitea-web target host
Build and test / build (push) Failing after 1m17s
Build and test / check (push) Failing after 1m18s
Build and test / docs (push) Failing after 1m26s
Build and test / test (push) Successful in 1m31s
2025-08-03 04:50:54 +02:00
oysteikt 59994ce740 Cargo.toml: update deps
Build and test / build (push) Successful in 1m29s
Build and test / check (push) Failing after 1m37s
Build and test / docs (push) Failing after 2m1s
Build and test / test (push) Failing after 2m29s
2025-07-11 20:37:16 +02:00
oysteikt b42cad0b52 flake.lock: bump 2025-07-11 20:36:58 +02:00
oysteikt 3c49ece1a9 flake.nix: add cargo-edit to devshell 2025-07-11 20:36:50 +02:00
oysteikt 5a5870d7de flake.lock: bump
Build and test / check (push) Has been cancelled
Build and test / docs (push) Has been cancelled
Build and test / build (push) Has been cancelled
Build and test / test (push) Has been cancelled
2025-05-07 10:43:24 +02:00
oysteikt e5303954c5 Cargo.lock: bump
Build and test / build (push) Has been cancelled
Build and test / check (push) Has been cancelled
Build and test / test (push) Has been cancelled
Build and test / docs (push) Has been cancelled
2025-05-05 10:15:00 +02:00
oysteikt c95d39a9ec flake.lock: bump
Build and test / build (push) Has been cancelled
Build and test / check (push) Has been cancelled
Build and test / test (push) Has been cancelled
Build and test / docs (push) Has been cancelled
2025-05-05 10:13:44 +02:00
oysteikt e910d29aa4 Rust edition 2024
Build and test / build (push) Successful in 59s
Build and test / check (push) Failing after 1m2s
Build and test / test (push) Successful in 1m42s
Build and test / docs (push) Successful in 1m19s
2025-02-26 16:39:34 +01:00
oysteikt 58a06bd930 common/types: move stuff from requests to types
Build and test / build (push) Successful in 56s
Build and test / check (push) Failing after 59s
Build and test / docs (push) Successful in 1m25s
Build and test / test (push) Successful in 1m38s
2025-02-25 12:15:39 +01:00
oysteikt 380a4aed2c commands: deduplicate logic in macros, add more macros
Build and test / build (push) Successful in 59s
Build and test / check (push) Failing after 1m2s
Build and test / test (push) Successful in 1m40s
Build and test / docs (push) Successful in 1m27s
2025-02-23 19:26:46 +01:00
oysteikt ed7f9a6917 commands: implement some more response parsers
Build and test / build (push) Successful in 1m1s
Build and test / test (push) Successful in 1m37s
Build and test / docs (push) Successful in 1m16s
Build and test / check (push) Failing after 1m0s
2025-02-23 16:41:15 +01:00
oysteikt 432f16ae2b Cargo fmt
Build and test / build (push) Successful in 57s
Build and test / check (push) Failing after 1m2s
Build and test / docs (push) Has been cancelled
Build and test / test (push) Has been cancelled
2025-02-23 16:40:06 +01:00
oysteikt 44ba3eb4dc commands: move ResponseAttributes parser out of Command
Build and test / build (push) Successful in 1m0s
Build and test / check (push) Failing after 52s
Build and test / test (push) Successful in 1m45s
Build and test / docs (push) Successful in 1m23s
2025-02-23 16:33:34 +01:00
oysteikt d80ebfc4cf flake.lock: bump
Build and test / check (push) Failing after 51s
Build and test / build (push) Successful in 1m1s
Build and test / docs (push) Has been cancelled
Build and test / test (push) Has been cancelled
2025-02-23 16:31:49 +01:00
oysteikt 9f07114401 common: move types into separate files 2025-02-23 16:31:49 +01:00
oysteikt 5e0fe71feb Move project from Projects to Grzegorz
Build and test / build (push) Successful in 58s
Build and test / check (push) Failing after 59s
Build and test / test (push) Successful in 1m33s
Build and test / docs (push) Successful in 1m4s
2025-01-06 16:32:13 +01:00
oysteikt 366f56da9e commands: fix some syntax errors reporting literals
Build and test / build (push) Successful in 59s
Build and test / check (push) Failing after 58s
Build and test / docs (push) Successful in 1m21s
Build and test / test (push) Successful in 1m37s
2024-12-14 00:19:25 +01:00
oysteikt 9cef59eb88 Implement some more commands 2024-12-14 00:14:02 +01:00
oysteikt abacb54c8d commands: add missing debug asserts
Build and test / build (push) Failing after 16s
Build and test / test (push) Failing after 15s
Build and test / check (push) Failing after 59s
Build and test / docs (push) Successful in 1m17s
2024-12-13 19:31:50 +01:00
oysteikt 86183e56ad commands: add some TODOs for assumptions made about syntax 2024-12-13 19:31:48 +01:00
oysteikt 6a9cd00275 response: remove leftover response types, add error codes
Build and test / check (push) Failing after 1m2s
Build and test / build (push) Successful in 1m3s
Build and test / test (push) Successful in 1m37s
Build and test / docs (push) Successful in 1m16s
2024-12-13 18:30:16 +01:00
oysteikt 9cb92741a4 Implement some more commands
Build and test / check (push) Failing after 13s
Build and test / test (push) Failing after 14s
Build and test / build (push) Successful in 57s
Build and test / docs (push) Successful in 1m12s
2024-12-13 18:20:03 +01:00
oysteikt cea3d3da04 commands: add a few TODOs
Build and test / build (push) Successful in 57s
Build and test / check (push) Failing after 57s
Build and test / docs (push) Successful in 1m8s
Build and test / test (push) Successful in 1m27s
2024-12-13 17:16:16 +01:00
oysteikt 87fa93fb1c format 2024-12-13 17:16:16 +01:00
oysteikt cf0db472e8 commands: verify key uniqueness for ResponseAttributes -> HashMap 2024-12-13 17:16:16 +01:00
oysteikt 4f6392e376 commands: use real Filter type 2024-12-13 17:16:16 +01:00
oysteikt 2fb97a9964 Move repo to Projects 2024-12-13 17:16:15 +01:00
oysteikt 48beaa7732 examples/mpd-client: format 2024-12-13 16:59:40 +01:00
oysteikt 2bd53462d7 .gitea/build-and-test: init
Build and test / check (push) Failing after 5m36s
Build and test / build (push) Successful in 10m23s
Build and test / test (push) Failing after 6m16s
Build and test / docs (push) Successful in 10m25s
2024-12-10 21:48:20 +01:00
oysteikt edeb0e3b78 .envrc: init 2024-12-05 18:10:11 +01:00
oysteikt 2ee6bbc582 Add more commands 2024-12-02 21:00:22 +01:00
oysteikt 3e512092bd Add existing command parsers to the main request parser 2024-12-01 19:16:44 +01:00
oysteikt 08104b3537 Implement some more commands 2024-12-01 18:31:34 +01:00
oysteikt 1561ae2e80 prefer unimplemented! for unimplemented functions 2024-11-30 03:36:00 +01:00
oysteikt d45502a43e commands: add derives for a few response types 2024-11-30 03:31:52 +01:00
oysteikt 4fada75fe9 commands: handle some more response parsing 2024-11-30 03:28:22 +01:00
oysteikt 184f9fc215 commands/stats: parse_response 2024-11-30 02:28:29 +01:00
oysteikt 74074bf9c7 commands: make macros usable without use statements 2024-11-30 02:28:10 +01:00
oysteikt 84f061a79f commands: use different datastructure for response attrs 2024-11-30 02:18:06 +01:00
oysteikt 472be6c083 flake.lock: bump 2024-11-30 01:57:57 +01:00
oysteikt 49e070a41d Continued development 2024-11-30 01:57:45 +01:00
oysteikt 8293c6e6e5 Initial commit 2024-11-05 22:47:35 +01:00
95 changed files with 224 additions and 2047 deletions
-2
View File
@@ -1,2 +0,0 @@
[registries]
pvv-git = { index = "sparse+https://git.pvv.ntnu.no/api/packages/Grzegorz/cargo/" }
+5 -5
View File
@@ -7,7 +7,7 @@ on:
jobs: jobs:
build: build:
runs-on: debian-latest runs-on: debian-latest-slim
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v6
@@ -18,7 +18,7 @@ jobs:
run: cargo build --verbose --release run: cargo build --verbose --release
check: check:
runs-on: debian-latest runs-on: debian-latest-slim
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v6
@@ -35,7 +35,7 @@ jobs:
run: cargo clippy run: cargo clippy
test: test:
runs-on: debian-latest runs-on: debian-latest-slim
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v6
- uses: cargo-bins/cargo-binstall@main - uses: cargo-bins/cargo-binstall@main
@@ -88,7 +88,7 @@ jobs:
known-hosts: "pages.pvv.ntnu.no ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH2QjfFB+city1SYqltkVqWACfo1j37k+oQQfj13mtgg" known-hosts: "pages.pvv.ntnu.no ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH2QjfFB+city1SYqltkVqWACfo1j37k+oQQfj13mtgg"
docs: docs:
runs-on: debian-latest runs-on: debian-latest-slim
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v6
@@ -102,7 +102,7 @@ jobs:
run: cargo doc --document-private-items --release run: cargo doc --document-private-items --release
- name: Transfer files - name: Transfer files
uses: https://git.pvv.ntnu.no/Projects/rsync-action@v2 uses: https://git.pvv.ntnu.no/Projects/rsync-action@v1
with: with:
source: target/doc/ source: target/doc/
target: ${{ gitea.ref_name }}/docs/ target: ${{ gitea.ref_name }}/docs/
+2
View File
@@ -1,3 +1,5 @@
/target /target
result result
result-* result-*
Cargo.lock
Generated
-900
View File
@@ -1,900 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "aho-corasick"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
dependencies = [
"memchr",
]
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "anyhow"
version = "1.0.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
[[package]]
name = "ascii-canvas"
version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef1e3e699d84ab1b0911a1010c5c106aa34ae89aeac103be5ce0c3859db1e891"
dependencies = [
"term",
]
[[package]]
name = "autocfg"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "bit-set"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3"
dependencies = [
"bit-vec",
]
[[package]]
name = "bit-vec"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
[[package]]
name = "bitflags"
version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "bumpalo"
version = "3.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
[[package]]
name = "bytes"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
[[package]]
name = "cc"
version = "1.2.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1"
dependencies = [
"find-msvc-tools",
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "chrono"
version = "0.4.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
dependencies = [
"iana-time-zone",
"js-sys",
"num-traits",
"serde",
"wasm-bindgen",
"windows-link",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "cpufeatures"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [
"libc",
]
[[package]]
name = "crypto-common"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "diff"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]]
name = "either"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "empidee"
version = "0.1.0"
dependencies = [
"anyhow",
"chrono",
"futures-util",
"indoc",
"lalrpop",
"lalrpop-util",
"paste",
"pretty_assertions",
"serde",
"thiserror",
"tokio",
]
[[package]]
name = "ena"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eabffdaee24bd1bf95c5ef7cec31260444317e72ea56c4c91750e8b7ee58d5f1"
dependencies = [
"log",
]
[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "find-msvc-tools"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
[[package]]
name = "fixedbitset"
version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99"
[[package]]
name = "futures-core"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
[[package]]
name = "futures-io"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
[[package]]
name = "futures-macro"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "futures-task"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"
[[package]]
name = "futures-util"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
dependencies = [
"futures-core",
"futures-io",
"futures-macro",
"futures-task",
"memchr",
"pin-project-lite",
"slab",
]
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "hashbrown"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
[[package]]
name = "iana-time-zone"
version = "0.1.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"log",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "indexmap"
version = "2.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]]
name = "indoc"
version = "2.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
dependencies = [
"rustversion",
]
[[package]]
name = "itertools"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
dependencies = [
"either",
]
[[package]]
name = "js-sys"
version = "0.3.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9"
dependencies = [
"once_cell",
"wasm-bindgen",
]
[[package]]
name = "keccak"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653"
dependencies = [
"cpufeatures",
]
[[package]]
name = "lalrpop"
version = "0.22.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba4ebbd48ce411c1d10fb35185f5a51a7bfa3d8b24b4e330d30c9e3a34129501"
dependencies = [
"ascii-canvas",
"bit-set",
"ena",
"itertools",
"lalrpop-util",
"petgraph",
"pico-args",
"regex",
"regex-syntax",
"sha3",
"string_cache",
"term",
"unicode-xid",
"walkdir",
]
[[package]]
name = "lalrpop-util"
version = "0.22.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5baa5e9ff84f1aefd264e6869907646538a52147a755d494517a8007fb48733"
dependencies = [
"regex-automata",
"rustversion",
]
[[package]]
name = "libc"
version = "0.2.184"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af"
[[package]]
name = "lock_api"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
dependencies = [
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
[[package]]
name = "memchr"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
[[package]]
name = "mio"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1"
dependencies = [
"libc",
"wasi",
"windows-sys",
]
[[package]]
name = "new_debug_unreachable"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
[[package]]
name = "parking_lot"
version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"windows-link",
]
[[package]]
name = "paste"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "petgraph"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772"
dependencies = [
"fixedbitset",
"indexmap",
]
[[package]]
name = "phf_shared"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
dependencies = [
"siphasher",
]
[[package]]
name = "pico-args"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
[[package]]
name = "pin-project-lite"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
[[package]]
name = "precomputed-hash"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
[[package]]
name = "pretty_assertions"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d"
dependencies = [
"diff",
"yansi",
]
[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_syscall"
version = "0.5.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
dependencies = [
"bitflags",
]
[[package]]
name = "regex"
version = "1.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
[[package]]
name = "rustversion"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[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.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "sha3"
version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60"
dependencies = [
"digest",
"keccak",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "siphasher"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e"
[[package]]
name = "slab"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
[[package]]
name = "smallvec"
version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
[[package]]
name = "socket2"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
dependencies = [
"libc",
"windows-sys",
]
[[package]]
name = "string_cache"
version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f"
dependencies = [
"new_debug_unreachable",
"parking_lot",
"phf_shared",
"precomputed-hash",
]
[[package]]
name = "syn"
version = "2.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "term"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8c27177b12a6399ffc08b98f76f7c9a1f4fe9fc967c784c5a071fa8d93cf7e1"
dependencies = [
"windows-sys",
]
[[package]]
name = "thiserror"
version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tokio"
version = "1.50.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d"
dependencies = [
"bytes",
"libc",
"mio",
"pin-project-lite",
"socket2",
"tokio-macros",
"windows-sys",
]
[[package]]
name = "tokio-macros"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "typenum"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "unicode-xid"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "walkdir"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
dependencies = [
"same-file",
"winapi-util",
]
[[package]]
name = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
name = "wasm-bindgen"
version = "0.2.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0"
dependencies = [
"cfg-if",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2"
dependencies = [
"bumpalo",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39129a682a6d2d841b6c429d0c51e5cb0ed1a03829d8b3d1e69a011e62cb3d3b"
dependencies = [
"unicode-ident",
]
[[package]]
name = "winapi-util"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [
"windows-sys",
]
[[package]]
name = "windows-core"
version = "0.62.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
dependencies = [
"windows-implement",
"windows-interface",
"windows-link",
"windows-result",
"windows-strings",
]
[[package]]
name = "windows-implement"
version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-interface"
version = "0.59.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-result"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-strings"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-sys"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
dependencies = [
"windows-link",
]
[[package]]
name = "yansi"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
+6 -7
View File
@@ -4,7 +4,6 @@ version = "0.1.0"
authors = [ authors = [
"Øystein Tveit <oysteikt@pvv.ntnu.no>" "Øystein Tveit <oysteikt@pvv.ntnu.no>"
] ]
license = "MIT"
description = "A rust implementation of the mpd protocol, both client and serverside" description = "A rust implementation of the mpd protocol, both client and serverside"
repository = "https://git.pvv.ntnu.no/Grzegorz/empidee" repository = "https://git.pvv.ntnu.no/Grzegorz/empidee"
documentation = "https://pages.pvv.ntnu.no/Grzegorz/empidee/main/docs/empidee/" documentation = "https://pages.pvv.ntnu.no/Grzegorz/empidee/main/docs/empidee/"
@@ -12,13 +11,13 @@ edition = "2024"
rust-version = "1.85.0" rust-version = "1.85.0"
[dependencies] [dependencies]
chrono = { version = "0.4.44", features = ["serde"] } chrono = { version = "0.4.42", features = ["serde"] }
futures-util = { version = "0.3.32", optional = true, features = ["io"] } futures-util = { version = "0.3.31", optional = true, features = ["io"] }
lalrpop-util = { version = "0.22.2", features = ["lexer"] } lalrpop-util = { version = "0.22.2", features = ["lexer"] }
paste = "1.0.15" paste = "1.0.15"
serde = { version = "1.0.228", features = ["derive"] } serde = { version = "1.0.228", features = ["derive"] }
thiserror = "2.0.18" thiserror = "2.0.17"
tokio = { version = "1.50.0", optional = true, features = ["io-util"] } tokio = { version = "1.48.0", optional = true, features = ["io-util"] }
[features] [features]
default = ["tokio"] default = ["tokio"]
@@ -26,10 +25,10 @@ futures = ["dep:futures-util"]
tokio = ["dep:tokio"] tokio = ["dep:tokio"]
[dev-dependencies] [dev-dependencies]
anyhow = "1.0.102" anyhow = "1.0.100"
indoc = "2.0.7" indoc = "2.0.7"
pretty_assertions = "1.4.1" pretty_assertions = "1.4.1"
tokio = { version = "1.50.0", features = ["macros", "net", "rt"] } tokio = { version = "1.48.0", features = ["macros", "net", "rt"] }
[build-dependencies] [build-dependencies]
lalrpop = "0.22.2" lalrpop = "0.22.2"
-21
View File
@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2025 Programvareverkstedet <projects@pvv.ntnu.no>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+3 -5
View File
@@ -4,11 +4,9 @@ use empidee::MpdClient;
async fn main() -> anyhow::Result<()> { async fn main() -> anyhow::Result<()> {
let socket = tokio::net::TcpSocket::new_v4()?; let socket = tokio::net::TcpSocket::new_v4()?;
let mut stream = socket.connect("127.0.0.1:6600".parse()?).await?; let mut stream = socket.connect("127.0.0.1:6600".parse()?).await?;
let mut client = MpdClient::new(&mut stream).await?;
println!( let mut client = MpdClient::new(&mut stream);
"Connected to MPD server: {}", println!("{}", client.read_initial_mpd_version().await?);
client.get_mpd_version().unwrap_or("unknown")
);
client.play(None).await?; client.play(None).await?;
Generated
+6 -6
View File
@@ -2,11 +2,11 @@
"nodes": { "nodes": {
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1775036866, "lastModified": 1764950072,
"narHash": "sha256-ZojAnPuCdy657PbTq5V0Y+AHKhZAIwSIT2cb8UgAz/U=", "narHash": "sha256-BmPWzogsG2GsXZtlT+MTcAWeDK5hkbGRZTeZNW42fwA=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "6201e203d09599479a3b3450ed24fa81537ebc4e", "rev": "f61125a668a320878494449750330ca58b78c557",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -29,11 +29,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1775099554, "lastModified": 1765075567,
"narHash": "sha256-3xBsGnGDLOFtnPZ1D3j2LU19wpAlYefRKTlkv648rU0=", "narHash": "sha256-KFDCdQcHJ0hE3Nt5Gm5enRIhmtEifAjpxgUQ3mzSJpA=",
"owner": "oxalica", "owner": "oxalica",
"repo": "rust-overlay", "repo": "rust-overlay",
"rev": "8d6387ed6d8e6e6672fd3ed4b61b59d44b124d99", "rev": "769156779b41e8787a46ca3d7d76443aaf68be6f",
"type": "github" "type": "github"
}, },
"original": { "original": {
-41
View File
@@ -42,46 +42,5 @@
RUST_SRC_PATH = "${toolchain}/lib/rustlib/src/rust/library"; RUST_SRC_PATH = "${toolchain}/lib/rustlib/src/rust/library";
}; };
}); });
packages = forAllSystems (system: pkgs: toolchain: let
rustPlatform = pkgs.makeRustPlatform {
cargo = toolchain;
rustc = toolchain;
};
cargoToml = builtins.fromTOML (builtins.readFile ./Cargo.toml);
src = lib.fileset.toSource {
root = ./.;
fileset = lib.fileset.unions [
./.cargo
./Cargo.toml
./Cargo.lock
./LICENSE
./README.md
./build.rs
./examples
./rustfmt.toml
./src
];
};
in {
default = self.packages.${system}.example-binaries;
example-binaries = rustPlatform.buildRustPackage {
pname = "empidee-example-bins";
inherit (cargoToml.package) version;
inherit src;
cargoLock.lockFile = ./Cargo.lock;
cargoBuildFlags = [ "--examples" ];
# TODO: avoid the binary variant with the hash at the end
postInstall = ''
find "$releaseDir"/examples -type f -executable -exec install -Dt "$out/bin" {} \;
'';
doCheck = true;
useNextest = true;
};
});
}; };
} }
+14 -39
View File
@@ -9,20 +9,18 @@ use crate::{Request, commands::*, types::SongPosition};
#[cfg(feature = "futures")] #[cfg(feature = "futures")]
use futures_util::{ use futures_util::{
AsyncBufReadExt, AsyncBufReadExt,
io::{AsyncRead, AsyncWrite, AsyncWriteExt, BufReader, BufWriter}, io::{AsyncRead, AsyncWrite, AsyncWriteExt, BufReader},
}; };
#[cfg(feature = "tokio")]
use tokio::io::{AsyncBufReadExt, AsyncRead, AsyncWrite, AsyncWriteExt, BufStream};
use thiserror::Error; use thiserror::Error;
#[cfg(feature = "tokio")]
use tokio::io::{AsyncBufReadExt, AsyncRead, AsyncWrite, AsyncWriteExt, BufReader};
pub struct MpdClient<'a, T> pub struct MpdClient<'a, T>
where where
T: AsyncWrite + AsyncRead + Unpin, T: AsyncWrite + AsyncRead + Unpin,
{ {
stream: BufStream<&'a mut T>, connection: &'a mut T,
mpd_version: Option<String>,
} }
#[derive(Error, Debug)] #[derive(Error, Debug)]
@@ -41,53 +39,30 @@ impl<'a, T> MpdClient<'a, T>
where where
T: AsyncWrite + AsyncRead + Unpin, T: AsyncWrite + AsyncRead + Unpin,
{ {
pub async fn new(connection: &'a mut T) -> Result<Self, MpdClientError> { pub fn new(connection: &'a mut T) -> Self {
let mut client = MpdClient { MpdClient { connection }
stream: BufStream::new(connection),
mpd_version: None,
};
client.read_initial_mpd_version().await?;
Ok(client)
} }
pub async fn wrap_existing(connection: &'a mut T, mpd_version: Option<String>) -> Self { pub async fn read_initial_mpd_version(&mut self) -> Result<String, MpdClientError> {
MpdClient { let mut reader = BufReader::new(&mut self.connection);
stream: BufStream::new(connection),
mpd_version,
}
}
pub fn into_connection(self) -> &'a mut T {
self.stream.into_inner()
}
pub fn get_mpd_version(&self) -> Option<&str> {
self.mpd_version.as_deref()
}
async fn read_initial_mpd_version(&mut self) -> Result<(), MpdClientError> {
let mut version_line = String::new(); let mut version_line = String::new();
self.stream reader
.read_line(&mut version_line) .read_line(&mut version_line)
.await .await
.map_err(MpdClientError::ConnectionError)?; .map_err(MpdClientError::ConnectionError)?;
self.mpd_version = Some(version_line.trim().to_string()); Ok(version_line.trim().to_string())
Ok(())
} }
async fn read_response(&mut self) -> Result<Vec<u8>, MpdClientError> { async fn read_response(&mut self) -> Result<Vec<u8>, MpdClientError> {
let mut response = Vec::new(); let mut response = Vec::new();
let mut reader = BufReader::new(&mut self.connection);
loop { loop {
let mut line = Vec::new(); let mut line = Vec::new();
let bytes_read = self let bytes_read = reader
.stream
.read_until(b'\n', &mut line) .read_until(b'\n', &mut line)
.await .await
.map_err(MpdClientError::ConnectionError)?; .map_err(MpdClientError::ConnectionError)?;
@@ -113,12 +88,12 @@ where
let message = Request::Play(position); let message = Request::Play(position);
let payload = message.serialize(); let payload = message.serialize();
self.stream self.connection
.write_all(payload.as_bytes()) .write_all(payload.as_bytes())
.await .await
.map_err(MpdClientError::ConnectionError)?; .map_err(MpdClientError::ConnectionError)?;
self.stream self.connection
.flush() .flush()
.await .await
.map_err(MpdClientError::ConnectionError)?; .map_err(MpdClientError::ConnectionError)?;
+37 -1
View File
@@ -116,7 +116,7 @@ where
/// This assumes the raw string starts with the command name, e.g. /// This assumes the raw string starts with the command name, e.g.
/// `command_name arg1 "arg2 arg3"` /// `command_name arg1 "arg2 arg3"`
fn parse_raw(raw: &str) -> Result<Self, RequestParserError> { fn parse_raw(raw: &str) -> Result<Self, RequestParserError> {
let (line, _rest) = raw let (line, rest) = raw
.split_once('\n') .split_once('\n')
.ok_or(RequestParserError::MissingNewline)?; .ok_or(RequestParserError::MissingNewline)?;
@@ -272,6 +272,12 @@ macro_rules! empty_command_request {
pub struct [<$name Request>]; pub struct [<$name Request>];
} }
impl paste::paste! { [<$name Request>] } {
pub fn new() -> Self {
Self
}
}
impl crate::commands::CommandRequest for paste::paste! { [<$name Request>] } { impl crate::commands::CommandRequest for paste::paste! { [<$name Request>] } {
const COMMAND: &'static str = $command_name; const COMMAND: &'static str = $command_name;
const MIN_ARGS: u32 = 0; const MIN_ARGS: u32 = 0;
@@ -315,6 +321,12 @@ macro_rules! empty_command_response {
pub struct [<$name Response>]; pub struct [<$name Response>];
} }
impl paste::paste! { [<$name Response>] } {
pub fn new() -> Self {
Self
}
}
impl crate::commands::CommandResponse for paste::paste! { [<$name Response>] } { impl crate::commands::CommandResponse for paste::paste! { [<$name Response>] } {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
@@ -341,6 +353,12 @@ macro_rules! single_item_command_request {
pub struct [<$name Request>] ($item_type); pub struct [<$name Request>] ($item_type);
} }
impl paste::paste! { [<$name Request>] } {
pub fn new(arg: $item_type) -> Self {
Self(arg)
}
}
impl crate::commands::CommandRequest for paste::paste! { [<$name Request>] } { impl crate::commands::CommandRequest for paste::paste! { [<$name Request>] } {
const COMMAND: &'static str = $command_name; const COMMAND: &'static str = $command_name;
const MIN_ARGS: u32 = 1; const MIN_ARGS: u32 = 1;
@@ -394,6 +412,12 @@ macro_rules! single_optional_item_command_request {
pub struct [<$name Request>] (Option<$item_type>); pub struct [<$name Request>] (Option<$item_type>);
} }
impl paste::paste! { [<$name Request>] } {
pub fn new(arg: Option<$item_type>) -> Self {
Self(arg)
}
}
impl crate::commands::CommandRequest for paste::paste! { [<$name Request>] } { impl crate::commands::CommandRequest for paste::paste! { [<$name Request>] } {
const COMMAND: &'static str = $command_name; const COMMAND: &'static str = $command_name;
const MIN_ARGS: u32 = 0; const MIN_ARGS: u32 = 0;
@@ -453,6 +477,12 @@ macro_rules! single_item_command_response {
pub struct [<$name Response>] ( $item_type ); pub struct [<$name Response>] ( $item_type );
} }
impl paste::paste! { [<$name Response>] } {
pub fn new(arg: $item_type) -> Self {
Self(arg)
}
}
impl crate::commands::CommandResponse for paste::paste! { [<$name Response>] } { impl crate::commands::CommandResponse for paste::paste! { [<$name Response>] } {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
@@ -497,6 +527,12 @@ macro_rules! multi_item_command_response {
pub struct [<$name Response>] ( Vec<$item_type> ); pub struct [<$name Response>] ( Vec<$item_type> );
} }
impl paste::paste! { [<$name Response>] } {
pub fn new(arg: Vec<$item_type>) -> Self {
Self(arg)
}
}
impl crate::commands::CommandResponse for paste::paste! { [<$name Response>] } { impl crate::commands::CommandResponse for paste::paste! { [<$name Response>] } {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
+1 -25
View File
@@ -15,12 +15,6 @@ empty_command_request!(Outputs, "outputs");
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct OutputsResponse(Vec<Output>); pub struct OutputsResponse(Vec<Output>);
impl OutputsResponse {
pub fn new(outputs: Vec<Output>) -> Self {
OutputsResponse(outputs)
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Output { pub struct Output {
pub id: AudioOutputId, pub id: AudioOutputId,
@@ -30,30 +24,12 @@ pub struct Output {
pub attribute: HashMap<String, String>, pub attribute: HashMap<String, String>,
} }
impl Output {
pub fn new(
id: AudioOutputId,
name: String,
plugin: String,
enabled: bool,
attribute: HashMap<String, String>,
) -> Self {
Output {
id,
name,
plugin,
enabled,
attribute,
}
}
}
impl CommandResponse for OutputsResponse { impl CommandResponse for OutputsResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
@@ -16,7 +16,7 @@ pub struct OutputSetRequest {
} }
impl OutputSetRequest { impl OutputSetRequest {
pub fn new(output_id: AudioOutputId, attribute_name: String, attribute_value: String) -> Self { fn new(output_id: AudioOutputId, attribute_name: String, attribute_value: String) -> Self {
Self { Self {
output_id, output_id,
attribute_name, attribute_name,
+1 -7
View File
@@ -15,18 +15,12 @@ pub struct ChannelsResponse {
pub channels: Vec<ChannelName>, pub channels: Vec<ChannelName>,
} }
impl ChannelsResponse {
pub fn new(channels: Vec<ChannelName>) -> Self {
ChannelsResponse { channels }
}
}
impl CommandResponse for ChannelsResponse { impl CommandResponse for ChannelsResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
+1 -13
View File
@@ -13,30 +13,18 @@ empty_command_request!(ReadMessages, "readmessages");
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ReadMessagesResponse(Vec<ReadMessagesResponseEntry>); pub struct ReadMessagesResponse(Vec<ReadMessagesResponseEntry>);
impl ReadMessagesResponse {
pub fn new(entries: Vec<ReadMessagesResponseEntry>) -> Self {
ReadMessagesResponse(entries)
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ReadMessagesResponseEntry { pub struct ReadMessagesResponseEntry {
channel: ChannelName, channel: ChannelName,
message: String, message: String,
} }
impl ReadMessagesResponseEntry {
pub fn new(channel: ChannelName, message: String) -> Self {
ReadMessagesResponseEntry { channel, message }
}
}
impl CommandResponse for ReadMessagesResponse { impl CommandResponse for ReadMessagesResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
+1 -1
View File
@@ -15,7 +15,7 @@ pub struct SendMessageRequest {
} }
impl SendMessageRequest { impl SendMessageRequest {
pub fn new(channel: ChannelName, message: String) -> Self { fn new(channel: ChannelName, message: String) -> Self {
Self { channel, message } Self { channel, message }
} }
} }
@@ -9,8 +9,8 @@ pub struct ProtocolDisable;
pub struct ProtocolDisableRequest(Vec<Feature>); pub struct ProtocolDisableRequest(Vec<Feature>);
impl ProtocolDisableRequest { impl ProtocolDisableRequest {
pub fn new(features: Vec<Feature>) -> Self { fn new(features: Vec<Feature>) -> Self {
ProtocolDisableRequest(features) Self(features)
} }
} }
@@ -9,8 +9,8 @@ pub struct ProtocolEnable;
pub struct ProtocolEnableRequest(Vec<Feature>); pub struct ProtocolEnableRequest(Vec<Feature>);
impl ProtocolEnableRequest { impl ProtocolEnableRequest {
pub fn new(features: Vec<Feature>) -> Self { fn new(features: Vec<Feature>) -> Self {
ProtocolEnableRequest(features) Self(features)
} }
} }
@@ -1,3 +1,5 @@
use std::u32;
use crate::{ use crate::{
commands::{Command, CommandRequest, RequestParserError, empty_command_response}, commands::{Command, CommandRequest, RequestParserError, empty_command_response},
request_tokenizer::RequestTokenizer, request_tokenizer::RequestTokenizer,
@@ -9,8 +11,8 @@ pub struct TagTypesDisable;
pub struct TagTypesDisableRequest(Vec<TagName>); pub struct TagTypesDisableRequest(Vec<TagName>);
impl TagTypesDisableRequest { impl TagTypesDisableRequest {
pub fn new(tag_types: Vec<TagName>) -> Self { fn new(tagnames: Vec<TagName>) -> Self {
TagTypesDisableRequest(tag_types) Self(tagnames)
} }
} }
@@ -9,8 +9,8 @@ pub struct TagTypesEnable;
pub struct TagTypesEnableRequest(Vec<TagName>); pub struct TagTypesEnableRequest(Vec<TagName>);
impl TagTypesEnableRequest { impl TagTypesEnableRequest {
pub fn new(tag_types: Vec<TagName>) -> Self { fn new(tagnames: Vec<TagName>) -> Self {
TagTypesEnableRequest(tag_types) Self(tagnames)
} }
} }
@@ -9,8 +9,8 @@ pub struct TagTypesReset;
pub struct TagTypesResetRequest(Vec<TagName>); pub struct TagTypesResetRequest(Vec<TagName>);
impl TagTypesResetRequest { impl TagTypesResetRequest {
pub fn new(tag_types: Vec<TagName>) -> Self { fn new(tagnames: Vec<TagName>) -> Self {
TagTypesResetRequest(tag_types) Self(tagnames)
} }
} }
+2 -2
View File
@@ -8,8 +8,8 @@ pub struct Pause;
pub struct PauseRequest(Option<bool>); pub struct PauseRequest(Option<bool>);
impl PauseRequest { impl PauseRequest {
pub fn new(state: Option<bool>) -> Self { fn new(toggle: Option<bool>) -> Self {
PauseRequest(state) Self(toggle)
} }
} }
@@ -14,12 +14,6 @@ pub struct SeekRequest {
pub time: TimeWithFractions, pub time: TimeWithFractions,
} }
impl SeekRequest {
pub fn new(songpos: SongPosition, time: TimeWithFractions) -> Self {
Self { songpos, time }
}
}
impl CommandRequest for SeekRequest { impl CommandRequest for SeekRequest {
const COMMAND: &'static str = "seek"; const COMMAND: &'static str = "seek";
const MIN_ARGS: u32 = 2; const MIN_ARGS: u32 = 2;
@@ -14,12 +14,6 @@ pub struct SeekCurRequest {
pub time: TimeWithFractions, pub time: TimeWithFractions,
} }
impl SeekCurRequest {
pub fn new(mode: SeekMode, time: TimeWithFractions) -> Self {
Self { mode, time }
}
}
impl CommandRequest for SeekCurRequest { impl CommandRequest for SeekCurRequest {
const COMMAND: &'static str = "seekcur"; const COMMAND: &'static str = "seekcur";
const MIN_ARGS: u32 = 1; const MIN_ARGS: u32 = 1;
@@ -14,12 +14,6 @@ pub struct SeekIdRequest {
pub time: TimeWithFractions, pub time: TimeWithFractions,
} }
impl SeekIdRequest {
pub fn new(songid: SongId, time: TimeWithFractions) -> Self {
Self { songid, time }
}
}
impl CommandRequest for SeekIdRequest { impl CommandRequest for SeekIdRequest {
const COMMAND: &'static str = "seekid"; const COMMAND: &'static str = "seekid";
const MIN_ARGS: u32 = 2; const MIN_ARGS: u32 = 2;
@@ -14,18 +14,12 @@ empty_command_request!(ListNeighbors, "listneighbors");
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ListNeighborsResponse(HashMap<String, String>); pub struct ListNeighborsResponse(HashMap<String, String>);
impl ListNeighborsResponse {
pub fn new(map: HashMap<String, String>) -> Self {
ListNeighborsResponse(map)
}
}
impl CommandResponse for ListNeighborsResponse { impl CommandResponse for ListNeighborsResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
@@ -14,12 +14,6 @@ pub struct MountRequest {
pub uri: Uri, pub uri: Uri,
} }
impl MountRequest {
pub fn new(path: MountPath, uri: Uri) -> Self {
MountRequest { path, uri }
}
}
impl CommandRequest for MountRequest { impl CommandRequest for MountRequest {
const COMMAND: &'static str = "mount"; const COMMAND: &'static str = "mount";
const MIN_ARGS: u32 = 2; const MIN_ARGS: u32 = 2;
@@ -10,12 +10,6 @@ pub struct Unmount;
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct UnmountRequest(MountPath); pub struct UnmountRequest(MountPath);
impl UnmountRequest {
pub fn new(path: MountPath) -> Self {
UnmountRequest(path)
}
}
impl CommandRequest for UnmountRequest { impl CommandRequest for UnmountRequest {
const COMMAND: &'static str = "unmount"; const COMMAND: &'static str = "unmount";
const MIN_ARGS: u32 = 1; const MIN_ARGS: u32 = 1;
+1 -13
View File
@@ -17,12 +17,6 @@ pub struct AlbumArtRequest {
offset: Offset, offset: Offset,
} }
impl AlbumArtRequest {
pub fn new(uri: Uri, offset: Offset) -> Self {
AlbumArtRequest { uri, offset }
}
}
impl CommandRequest for AlbumArtRequest { impl CommandRequest for AlbumArtRequest {
const COMMAND: &'static str = "albumart"; const COMMAND: &'static str = "albumart";
const MIN_ARGS: u32 = 2; const MIN_ARGS: u32 = 2;
@@ -75,18 +69,12 @@ pub struct AlbumArtResponse {
pub binary: Vec<u8>, pub binary: Vec<u8>,
} }
impl AlbumArtResponse {
pub fn new(size: usize, binary: Vec<u8>) -> Self {
AlbumArtResponse { size, binary }
}
}
impl CommandResponse for AlbumArtResponse { impl CommandResponse for AlbumArtResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
+1 -13
View File
@@ -18,12 +18,6 @@ pub struct CountRequest {
group: Option<GroupType>, group: Option<GroupType>,
} }
impl CountRequest {
pub fn new(filter: Filter, group: Option<GroupType>) -> Self {
CountRequest { filter, group }
}
}
impl CommandRequest for CountRequest { impl CommandRequest for CountRequest {
const COMMAND: &'static str = "count"; const COMMAND: &'static str = "count";
const MIN_ARGS: u32 = 1; const MIN_ARGS: u32 = 1;
@@ -90,18 +84,12 @@ pub struct CountResponse {
pub playtime: u64, pub playtime: u64,
} }
impl CountResponse {
pub fn new(songs: usize, playtime: u64) -> Self {
CountResponse { songs, playtime }
}
}
impl CommandResponse for CountResponse { impl CommandResponse for CountResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
+1 -17
View File
@@ -17,16 +17,6 @@ pub struct FindRequest {
window: Option<WindowRange>, window: Option<WindowRange>,
} }
impl FindRequest {
pub fn new(filter: Filter, sort: Option<Sort>, window: Option<WindowRange>) -> Self {
Self {
filter,
sort,
window,
}
}
}
impl CommandRequest for FindRequest { impl CommandRequest for FindRequest {
const COMMAND: &'static str = "find"; const COMMAND: &'static str = "find";
const MIN_ARGS: u32 = 1; const MIN_ARGS: u32 = 1;
@@ -121,18 +111,12 @@ impl CommandRequest for FindRequest {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct FindResponse(Vec<DbSongInfo>); pub struct FindResponse(Vec<DbSongInfo>);
impl FindResponse {
pub fn new(items: Vec<DbSongInfo>) -> Self {
FindResponse(items)
}
}
impl CommandResponse for FindResponse { impl CommandResponse for FindResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
-16
View File
@@ -17,22 +17,6 @@ pub struct FindAddRequest {
position: Option<SongPosition>, position: Option<SongPosition>,
} }
impl FindAddRequest {
pub fn new(
filter: Filter,
sort: Option<Sort>,
window: Option<WindowRange>,
position: Option<SongPosition>,
) -> Self {
Self {
filter,
sort,
window,
position,
}
}
}
impl CommandRequest for FindAddRequest { impl CommandRequest for FindAddRequest {
const COMMAND: &'static str = "findadd"; const COMMAND: &'static str = "findadd";
const MIN_ARGS: u32 = 1; const MIN_ARGS: u32 = 1;
@@ -17,18 +17,12 @@ pub struct GetFingerprintResponse {
pub chromaprint: String, pub chromaprint: String,
} }
impl GetFingerprintResponse {
pub fn new(chromaprint: String) -> Self {
Self { chromaprint }
}
}
impl CommandResponse for GetFingerprintResponse { impl CommandResponse for GetFingerprintResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
+1 -23
View File
@@ -18,22 +18,6 @@ pub struct ListRequest {
window: Option<WindowRange>, window: Option<WindowRange>,
} }
impl ListRequest {
pub fn new(
tagname: TagName,
filter: Option<Filter>,
groups: Vec<GroupType>,
window: Option<WindowRange>,
) -> Self {
Self {
tagname,
filter,
groups,
window,
}
}
}
impl CommandRequest for ListRequest { impl CommandRequest for ListRequest {
const COMMAND: &'static str = "list"; const COMMAND: &'static str = "list";
const MIN_ARGS: u32 = 1; const MIN_ARGS: u32 = 1;
@@ -154,18 +138,12 @@ impl CommandRequest for ListRequest {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ListResponse(Vec<String>); pub struct ListResponse(Vec<String>);
impl ListResponse {
pub fn new(items: Vec<String>) -> Self {
ListResponse(items)
}
}
impl CommandResponse for ListResponse { impl CommandResponse for ListResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
+1 -7
View File
@@ -16,18 +16,12 @@ single_optional_item_command_request!(ListAll, "listall", Uri);
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ListAllResponse(Vec<DbSelectionPrintResponse>); pub struct ListAllResponse(Vec<DbSelectionPrintResponse>);
impl ListAllResponse {
pub fn new(items: Vec<DbSelectionPrintResponse>) -> Self {
ListAllResponse(items)
}
}
impl CommandResponse for ListAllResponse { impl CommandResponse for ListAllResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
+1 -7
View File
@@ -16,14 +16,8 @@ single_optional_item_command_request!(ListAllInfo, "listallinfo", Uri);
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ListAllInfoResponse(Vec<DbSelectionPrintResponse>); pub struct ListAllInfoResponse(Vec<DbSelectionPrintResponse>);
impl ListAllInfoResponse {
pub fn new(items: Vec<DbSelectionPrintResponse>) -> Self {
ListAllInfoResponse(items)
}
}
impl CommandResponse for ListAllInfoResponse { impl CommandResponse for ListAllInfoResponse {
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
+1 -7
View File
@@ -15,18 +15,12 @@ single_optional_item_command_request!(ListFiles, "listfiles", Uri);
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ListFilesResponse(Vec<DbDirectoryInfo>); pub struct ListFilesResponse(Vec<DbDirectoryInfo>);
impl ListFilesResponse {
pub fn new(items: Vec<DbDirectoryInfo>) -> Self {
ListFilesResponse(items)
}
}
impl CommandResponse for ListFilesResponse { impl CommandResponse for ListFilesResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
+1 -7
View File
@@ -15,18 +15,12 @@ single_optional_item_command_request!(LsInfo, "lsinfo", Uri);
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct LsInfoResponse(Vec<DbSelectionPrintResponse>); pub struct LsInfoResponse(Vec<DbSelectionPrintResponse>);
impl LsInfoResponse {
pub fn new(items: Vec<DbSelectionPrintResponse>) -> Self {
LsInfoResponse(items)
}
}
impl CommandResponse for LsInfoResponse { impl CommandResponse for LsInfoResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
+1 -7
View File
@@ -15,18 +15,12 @@ single_item_command_request!(ReadComments, "readcomments", Uri);
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ReadCommentsResponse(HashMap<String, String>); pub struct ReadCommentsResponse(HashMap<String, String>);
impl ReadCommentsResponse {
pub fn new(comments: HashMap<String, String>) -> Self {
ReadCommentsResponse(comments)
}
}
impl CommandResponse for ReadCommentsResponse { impl CommandResponse for ReadCommentsResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
+1 -17
View File
@@ -19,12 +19,6 @@ pub struct ReadPictureRequest {
pub offset: Offset, pub offset: Offset,
} }
impl ReadPictureRequest {
pub fn new(uri: Uri, offset: Offset) -> Self {
Self { uri, offset }
}
}
impl CommandRequest for ReadPictureRequest { impl CommandRequest for ReadPictureRequest {
const COMMAND: &'static str = "readpicture"; const COMMAND: &'static str = "readpicture";
const MIN_ARGS: u32 = 2; const MIN_ARGS: u32 = 2;
@@ -78,22 +72,12 @@ pub struct ReadPictureResponse {
pub mimetype: Option<String>, pub mimetype: Option<String>,
} }
impl ReadPictureResponse {
pub fn new(size: usize, binary: Vec<u8>, mimetype: Option<String>) -> Self {
Self {
size,
binary,
mimetype,
}
}
}
impl CommandResponse for ReadPictureResponse { impl CommandResponse for ReadPictureResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
+1 -7
View File
@@ -19,18 +19,12 @@ pub struct RescanResponse {
pub updating_db: usize, pub updating_db: usize,
} }
impl RescanResponse {
pub fn new(updating_db: usize) -> Self {
RescanResponse { updating_db }
}
}
impl CommandResponse for RescanResponse { impl CommandResponse for RescanResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
+1 -17
View File
@@ -17,16 +17,6 @@ pub struct SearchRequest {
window: Option<WindowRange>, window: Option<WindowRange>,
} }
impl SearchRequest {
pub fn new(filter: Filter, sort: Option<Sort>, window: Option<WindowRange>) -> Self {
Self {
filter,
sort,
window,
}
}
}
impl CommandRequest for SearchRequest { impl CommandRequest for SearchRequest {
const COMMAND: &'static str = "search"; const COMMAND: &'static str = "search";
const MIN_ARGS: u32 = 1; const MIN_ARGS: u32 = 1;
@@ -121,14 +111,8 @@ impl CommandRequest for SearchRequest {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SearchResponse(Vec<DbSongInfo>); pub struct SearchResponse(Vec<DbSongInfo>);
impl SearchResponse {
pub fn new(items: Vec<DbSongInfo>) -> Self {
SearchResponse(items)
}
}
impl CommandResponse for SearchResponse { impl CommandResponse for SearchResponse {
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
-16
View File
@@ -17,22 +17,6 @@ pub struct SearchAddRequest {
position: Option<SongPosition>, position: Option<SongPosition>,
} }
impl SearchAddRequest {
pub fn new(
filter: Filter,
sort: Option<Sort>,
window: Option<WindowRange>,
position: Option<SongPosition>,
) -> Self {
Self {
filter,
sort,
window,
position,
}
}
}
impl CommandRequest for SearchAddRequest { impl CommandRequest for SearchAddRequest {
const COMMAND: &'static str = "searchadd"; const COMMAND: &'static str = "searchadd";
const MIN_ARGS: u32 = 1; const MIN_ARGS: u32 = 1;
@@ -18,24 +18,6 @@ pub struct SearchAddPlRequest {
position: Option<SongPosition>, position: Option<SongPosition>,
} }
impl SearchAddPlRequest {
pub fn new(
playlist_name: PlaylistName,
filter: Filter,
sort: Option<Sort>,
window: Option<WindowRange>,
position: Option<SongPosition>,
) -> Self {
Self {
playlist_name,
filter,
sort,
window,
position,
}
}
}
impl CommandRequest for SearchAddPlRequest { impl CommandRequest for SearchAddPlRequest {
const COMMAND: &'static str = "searchaddpl"; const COMMAND: &'static str = "searchaddpl";
const MIN_ARGS: u32 = 2; const MIN_ARGS: u32 = 2;
+1 -13
View File
@@ -18,12 +18,6 @@ pub struct SearchCountRequest {
group: Option<GroupType>, group: Option<GroupType>,
} }
impl SearchCountRequest {
pub fn new(filter: Filter, group: Option<GroupType>) -> Self {
Self { filter, group }
}
}
impl CommandRequest for SearchCountRequest { impl CommandRequest for SearchCountRequest {
const COMMAND: &'static str = "searchcount"; const COMMAND: &'static str = "searchcount";
const MIN_ARGS: u32 = 1; const MIN_ARGS: u32 = 1;
@@ -91,14 +85,8 @@ pub struct SearchCountResponse {
pub playtime: Seconds, pub playtime: Seconds,
} }
impl SearchCountResponse {
pub fn new(songs: usize, playtime: Seconds) -> Self {
Self { songs, playtime }
}
}
impl CommandResponse for SearchCountResponse { impl CommandResponse for SearchCountResponse {
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
+1 -7
View File
@@ -19,18 +19,12 @@ pub struct UpdateResponse {
updating_db: usize, updating_db: usize,
} }
impl UpdateResponse {
pub fn new(updating_db: usize) -> Self {
UpdateResponse { updating_db }
}
}
impl CommandResponse for UpdateResponse { impl CommandResponse for UpdateResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
@@ -6,7 +6,6 @@ use crate::{
pub struct MixRampDelay; pub struct MixRampDelay;
single_item_command_request!(MixRampDelay, "mixrampdelay", Seconds); single_item_command_request!(MixRampDelay, "mixrampdelay", Seconds);
empty_command_response!(MixRampDelay); empty_command_response!(MixRampDelay);
impl Command for MixRampDelay { impl Command for MixRampDelay {
-6
View File
@@ -7,12 +7,6 @@ pub struct Random;
pub struct RandomRequest(bool); pub struct RandomRequest(bool);
impl RandomRequest {
pub fn new(state: bool) -> Self {
Self(state)
}
}
impl CommandRequest for RandomRequest { impl CommandRequest for RandomRequest {
const COMMAND: &'static str = "random"; const COMMAND: &'static str = "random";
const MIN_ARGS: u32 = 1; const MIN_ARGS: u32 = 1;
-6
View File
@@ -7,12 +7,6 @@ pub struct Repeat;
pub struct RepeatRequest(bool); pub struct RepeatRequest(bool);
impl RepeatRequest {
pub fn new(state: bool) -> Self {
RepeatRequest(state)
}
}
impl CommandRequest for RepeatRequest { impl CommandRequest for RepeatRequest {
const COMMAND: &'static str = "repeat"; const COMMAND: &'static str = "repeat";
const MIN_ARGS: u32 = 1; const MIN_ARGS: u32 = 1;
@@ -17,18 +17,12 @@ pub struct ReplayGainStatusResponse {
pub replay_gain_mode: ReplayGainModeMode, pub replay_gain_mode: ReplayGainModeMode,
} }
impl ReplayGainStatusResponse {
pub fn new(replay_gain_mode: ReplayGainModeMode) -> Self {
Self { replay_gain_mode }
}
}
impl CommandResponse for ReplayGainStatusResponse { impl CommandResponse for ReplayGainStatusResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
@@ -23,28 +23,12 @@ pub struct CurrentSongResponse {
song_info: DbSongInfo, song_info: DbSongInfo,
} }
impl CurrentSongResponse {
pub fn new(
position: SongPosition,
id: SongId,
priority: Option<Priority>,
song_info: DbSongInfo,
) -> Self {
Self {
position,
id,
priority,
song_info,
}
}
}
impl CommandResponse for CurrentSongResponse { impl CommandResponse for CurrentSongResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
-6
View File
@@ -10,12 +10,6 @@ pub struct Idle;
pub struct IdleRequest(Option<Vec<SubSystem>>); pub struct IdleRequest(Option<Vec<SubSystem>>);
impl IdleRequest {
pub fn new(subsystems: Option<Vec<SubSystem>>) -> Self {
IdleRequest(subsystems)
}
}
impl CommandRequest for IdleRequest { impl CommandRequest for IdleRequest {
const COMMAND: &'static str = "idle"; const COMMAND: &'static str = "idle";
const MIN_ARGS: u32 = 0; const MIN_ARGS: u32 = 0;
+1 -23
View File
@@ -24,34 +24,12 @@ pub struct StatsResponse {
pub db_update: Option<u64>, pub db_update: Option<u64>,
} }
impl StatsResponse {
pub fn new(
uptime: u64,
playtime: u64,
artists: Option<u64>,
albums: Option<u64>,
songs: Option<u64>,
db_playtime: Option<u64>,
db_update: Option<u64>,
) -> Self {
Self {
uptime,
playtime,
artists,
albums,
songs,
db_playtime,
db_update,
}
}
}
impl CommandResponse for StatsResponse { impl CommandResponse for StatsResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
+1 -57
View File
@@ -65,68 +65,12 @@ pub struct StatusResponse {
pub last_loaded_playlist: Option<String>, pub last_loaded_playlist: Option<String>,
} }
impl StatusResponse {
pub fn new(
partition: String,
volume: Option<u8>,
repeat: bool,
random: bool,
single: BoolOrOneshot,
consume: BoolOrOneshot,
playlist: u32,
playlist_length: u64,
state: StatusResponseState,
song: Option<SongPosition>,
song_id: Option<SongId>,
next_song: Option<SongPosition>,
next_song_id: Option<SongId>,
time: Option<(u64, u64)>,
elapsed: Option<f64>,
duration: Option<f64>,
bitrate: Option<u32>,
xfade: Option<u32>,
mixrampdb: Option<f64>,
mixrampdelay: Option<f64>,
audio: Option<Audio>,
updating_db: Option<u64>,
error: Option<String>,
last_loaded_playlist: Option<String>,
) -> Self {
Self {
partition,
volume,
repeat,
random,
single,
consume,
playlist,
playlist_length,
state,
song,
song_id,
next_song,
next_song_id,
time,
elapsed,
duration,
bitrate,
xfade,
mixrampdb,
mixrampdelay,
audio,
updating_db,
error,
last_loaded_playlist,
}
}
}
impl CommandResponse for StatusResponse { impl CommandResponse for StatusResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
-6
View File
@@ -14,12 +14,6 @@ pub struct AddRequest {
position: Option<SongPosition>, position: Option<SongPosition>,
} }
impl AddRequest {
pub fn new(uri: Uri, position: Option<SongPosition>) -> Self {
Self { uri, position }
}
}
impl CommandRequest for AddRequest { impl CommandRequest for AddRequest {
const COMMAND: &'static str = "add"; const COMMAND: &'static str = "add";
const MIN_ARGS: u32 = 1; const MIN_ARGS: u32 = 1;
+1 -13
View File
@@ -15,12 +15,6 @@ pub struct AddIdRequest {
pub position: Option<SongPosition>, pub position: Option<SongPosition>,
} }
impl AddIdRequest {
pub fn new(uri: Uri, position: Option<SongPosition>) -> Self {
Self { uri, position }
}
}
impl CommandRequest for AddIdRequest { impl CommandRequest for AddIdRequest {
const COMMAND: &'static str = "addid"; const COMMAND: &'static str = "addid";
const MIN_ARGS: u32 = 1; const MIN_ARGS: u32 = 1;
@@ -75,18 +69,12 @@ pub struct AddIdResponse {
pub id: SongId, pub id: SongId,
} }
impl AddIdResponse {
pub fn new(id: SongId) -> Self {
Self { id }
}
}
impl CommandResponse for AddIdResponse { impl CommandResponse for AddIdResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
-10
View File
@@ -15,16 +15,6 @@ pub struct AddTagIdRequest {
pub tag_value: TagValue, pub tag_value: TagValue,
} }
impl AddTagIdRequest {
pub fn new(songid: SongId, tag_name: TagName, tag_value: TagValue) -> Self {
Self {
songid,
tag_name,
tag_value,
}
}
}
impl CommandRequest for AddTagIdRequest { impl CommandRequest for AddTagIdRequest {
const COMMAND: &'static str = "addtagid"; const COMMAND: &'static str = "addtagid";
const MIN_ARGS: u32 = 3; const MIN_ARGS: u32 = 3;
-6
View File
@@ -14,12 +14,6 @@ pub struct ClearTagIdRequest {
pub tag_name: TagName, pub tag_name: TagName,
} }
impl ClearTagIdRequest {
pub fn new(songid: SongId, tag_name: TagName) -> Self {
Self { songid, tag_name }
}
}
impl CommandRequest for ClearTagIdRequest { impl CommandRequest for ClearTagIdRequest {
const COMMAND: &'static str = "cleartagid"; const COMMAND: &'static str = "cleartagid";
const MIN_ARGS: u32 = 2; const MIN_ARGS: u32 = 2;
-6
View File
@@ -14,12 +14,6 @@ pub struct MoveRequest {
pub to: AbsouluteRelativeSongPosition, pub to: AbsouluteRelativeSongPosition,
} }
impl MoveRequest {
pub fn new(from_or_range: OneOrRange, to: AbsouluteRelativeSongPosition) -> Self {
Self { from_or_range, to }
}
}
impl CommandRequest for MoveRequest { impl CommandRequest for MoveRequest {
const COMMAND: &'static str = "move"; const COMMAND: &'static str = "move";
const MIN_ARGS: u32 = 2; const MIN_ARGS: u32 = 2;
-6
View File
@@ -14,12 +14,6 @@ pub struct MoveIdRequest {
pub to: AbsouluteRelativeSongPosition, pub to: AbsouluteRelativeSongPosition,
} }
impl MoveIdRequest {
pub fn new(id: SongId, to: AbsouluteRelativeSongPosition) -> Self {
Self { id, to }
}
}
impl CommandRequest for MoveIdRequest { impl CommandRequest for MoveIdRequest {
const COMMAND: &'static str = "moveid"; const COMMAND: &'static str = "moveid";
const MIN_ARGS: u32 = 2; const MIN_ARGS: u32 = 2;
+2 -8
View File
@@ -13,22 +13,16 @@ empty_command_request!(Playlist, "playlist");
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PlaylistResponse(Vec<Uri>); pub struct PlaylistResponse(Vec<Uri>);
impl PlaylistResponse {
pub fn new(items: Vec<Uri>) -> Self {
PlaylistResponse(items)
}
}
impl CommandResponse for PlaylistResponse { impl CommandResponse for PlaylistResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
fn parse(_parts: ResponseAttributes<'_>) -> Result<Self, ResponseParserError> { fn parse(parts: ResponseAttributes<'_>) -> Result<Self, ResponseParserError> {
unimplemented!() unimplemented!()
} }
} }
+1 -33
View File
@@ -18,16 +18,6 @@ pub struct PlaylistFindRequest {
window: Option<WindowRange>, window: Option<WindowRange>,
} }
impl PlaylistFindRequest {
pub fn new(filter: Filter, sort: Option<Sort>, window: Option<WindowRange>) -> Self {
Self {
filter,
sort,
window,
}
}
}
impl CommandRequest for PlaylistFindRequest { impl CommandRequest for PlaylistFindRequest {
const COMMAND: &'static str = "playlistfind"; const COMMAND: &'static str = "playlistfind";
const MIN_ARGS: u32 = 1; const MIN_ARGS: u32 = 1;
@@ -122,12 +112,6 @@ impl CommandRequest for PlaylistFindRequest {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PlaylistFindResponse(Vec<PlaylistFindResponseEntry>); pub struct PlaylistFindResponse(Vec<PlaylistFindResponseEntry>);
impl PlaylistFindResponse {
pub fn new(items: Vec<PlaylistFindResponseEntry>) -> Self {
PlaylistFindResponse(items)
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PlaylistFindResponseEntry { pub struct PlaylistFindResponseEntry {
pub position: SongPosition, pub position: SongPosition,
@@ -136,28 +120,12 @@ pub struct PlaylistFindResponseEntry {
pub song_info: DbSongInfo, pub song_info: DbSongInfo,
} }
impl PlaylistFindResponseEntry {
pub fn new(
position: SongPosition,
id: SongId,
priority: Option<Priority>,
song_info: DbSongInfo,
) -> Self {
Self {
position,
id,
priority,
song_info,
}
}
}
impl CommandResponse for PlaylistFindResponse { impl CommandResponse for PlaylistFindResponse {
fn into_response_enum(self) -> Response { fn into_response_enum(self) -> Response {
todo!() todo!()
} }
fn from_response_enum(_response: Response) -> Option<Self> { fn from_response_enum(response: Response) -> Option<Self> {
todo!() todo!()
} }
+2 -24
View File
@@ -13,12 +13,6 @@ single_item_command_request!(PlaylistId, "playlistid", SongId);
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PlaylistIdResponse(Vec<PlaylistIdResponseEntry>); pub struct PlaylistIdResponse(Vec<PlaylistIdResponseEntry>);
impl PlaylistIdResponse {
pub fn new(items: Vec<PlaylistIdResponseEntry>) -> Self {
PlaylistIdResponse(items)
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PlaylistIdResponseEntry { pub struct PlaylistIdResponseEntry {
pub position: SongPosition, pub position: SongPosition,
@@ -27,32 +21,16 @@ pub struct PlaylistIdResponseEntry {
pub song_info: DbSongInfo, pub song_info: DbSongInfo,
} }
impl PlaylistIdResponseEntry {
pub fn new(
position: SongPosition,
id: SongId,
priority: Option<Priority>,
song_info: DbSongInfo,
) -> Self {
PlaylistIdResponseEntry {
position,
id,
priority,
song_info,
}
}
}
impl CommandResponse for PlaylistIdResponse { impl CommandResponse for PlaylistIdResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
fn parse(_parts: ResponseAttributes<'_>) -> Result<Self, ResponseParserError> { fn parse(parts: ResponseAttributes<'_>) -> Result<Self, ResponseParserError> {
unimplemented!() unimplemented!()
} }
} }
+1 -23
View File
@@ -15,12 +15,6 @@ single_optional_item_command_request!(PlaylistInfo, "playlistinfo", OneOrRange);
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PlaylistInfoResponse(Vec<PlaylistInfoResponseEntry>); pub struct PlaylistInfoResponse(Vec<PlaylistInfoResponseEntry>);
impl PlaylistInfoResponse {
pub fn new(items: Vec<PlaylistInfoResponseEntry>) -> Self {
PlaylistInfoResponse(items)
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PlaylistInfoResponseEntry { pub struct PlaylistInfoResponseEntry {
pub position: SongPosition, pub position: SongPosition,
@@ -29,28 +23,12 @@ pub struct PlaylistInfoResponseEntry {
pub song_info: DbSongInfo, pub song_info: DbSongInfo,
} }
impl PlaylistInfoResponseEntry {
pub fn new(
position: SongPosition,
id: SongId,
priority: Option<Priority>,
song_info: DbSongInfo,
) -> Self {
PlaylistInfoResponseEntry {
position,
id,
priority,
song_info,
}
}
}
impl CommandResponse for PlaylistInfoResponse { impl CommandResponse for PlaylistInfoResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
+2 -34
View File
@@ -17,16 +17,6 @@ pub struct PlaylistSearchRequest {
window: Option<WindowRange>, window: Option<WindowRange>,
} }
impl PlaylistSearchRequest {
pub fn new(filter: Filter, sort: Option<Sort>, window: Option<WindowRange>) -> Self {
Self {
filter,
sort,
window,
}
}
}
impl CommandRequest for PlaylistSearchRequest { impl CommandRequest for PlaylistSearchRequest {
const COMMAND: &'static str = "playlistsearch"; const COMMAND: &'static str = "playlistsearch";
const MIN_ARGS: u32 = 1; const MIN_ARGS: u32 = 1;
@@ -121,12 +111,6 @@ impl CommandRequest for PlaylistSearchRequest {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PlaylistSearchResponse(Vec<PlaylistSearchResponseEntry>); pub struct PlaylistSearchResponse(Vec<PlaylistSearchResponseEntry>);
impl PlaylistSearchResponse {
pub fn new(items: Vec<PlaylistSearchResponseEntry>) -> Self {
PlaylistSearchResponse(items)
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PlaylistSearchResponseEntry { pub struct PlaylistSearchResponseEntry {
pub position: SongPosition, pub position: SongPosition,
@@ -135,24 +119,8 @@ pub struct PlaylistSearchResponseEntry {
pub song_info: DbSongInfo, pub song_info: DbSongInfo,
} }
impl PlaylistSearchResponseEntry {
pub fn new(
position: SongPosition,
id: SongId,
priority: Option<Priority>,
song_info: DbSongInfo,
) -> Self {
Self {
position,
id,
priority,
song_info,
}
}
}
impl CommandResponse for PlaylistSearchResponse { impl CommandResponse for PlaylistSearchResponse {
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
@@ -160,7 +128,7 @@ impl CommandResponse for PlaylistSearchResponse {
todo!() todo!()
} }
fn parse(_parts: ResponseAttributes<'_>) -> Result<Self, ResponseParserError> { fn parse(parts: ResponseAttributes<'_>) -> Result<Self, ResponseParserError> {
unimplemented!() unimplemented!()
} }
} }
+2 -30
View File
@@ -15,12 +15,6 @@ pub struct PlChangesRequest {
pub window: Option<WindowRange>, pub window: Option<WindowRange>,
} }
impl PlChangesRequest {
pub fn new(version: PlaylistVersion, window: Option<WindowRange>) -> Self {
Self { version, window }
}
}
impl CommandRequest for PlChangesRequest { impl CommandRequest for PlChangesRequest {
const COMMAND: &'static str = "plchanges"; const COMMAND: &'static str = "plchanges";
const MIN_ARGS: u32 = 1; const MIN_ARGS: u32 = 1;
@@ -77,12 +71,6 @@ impl CommandRequest for PlChangesRequest {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PlChangesResponse(Vec<PlChangesResponseEntry>); pub struct PlChangesResponse(Vec<PlChangesResponseEntry>);
impl PlChangesResponse {
pub fn new(items: Vec<PlChangesResponseEntry>) -> Self {
PlChangesResponse(items)
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PlChangesResponseEntry { pub struct PlChangesResponseEntry {
pub position: SongPosition, pub position: SongPosition,
@@ -91,24 +79,8 @@ pub struct PlChangesResponseEntry {
pub song_info: DbSongInfo, pub song_info: DbSongInfo,
} }
impl PlChangesResponseEntry {
pub fn new(
position: SongPosition,
id: SongId,
priority: Option<Priority>,
song_info: DbSongInfo,
) -> Self {
PlChangesResponseEntry {
position,
id,
priority,
song_info,
}
}
}
impl CommandResponse for PlChangesResponse { impl CommandResponse for PlChangesResponse {
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
@@ -116,7 +88,7 @@ impl CommandResponse for PlChangesResponse {
todo!() todo!()
} }
fn parse(_parts: ResponseAttributes<'_>) -> Result<Self, ResponseParserError> { fn parse(parts: ResponseAttributes<'_>) -> Result<Self, ResponseParserError> {
unimplemented!() unimplemented!()
} }
} }
+2 -20
View File
@@ -15,12 +15,6 @@ pub struct PlChangesPosIdRequest {
pub window: Option<WindowRange>, pub window: Option<WindowRange>,
} }
impl PlChangesPosIdRequest {
pub fn new(version: PlaylistVersion, window: Option<WindowRange>) -> Self {
Self { version, window }
}
}
impl CommandRequest for PlChangesPosIdRequest { impl CommandRequest for PlChangesPosIdRequest {
const COMMAND: &'static str = "plchangesposid"; const COMMAND: &'static str = "plchangesposid";
const MIN_ARGS: u32 = 1; const MIN_ARGS: u32 = 1;
@@ -77,12 +71,6 @@ impl CommandRequest for PlChangesPosIdRequest {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PlChangesPosIdResponse(Vec<PlChangesPosIdResponseEntry>); pub struct PlChangesPosIdResponse(Vec<PlChangesPosIdResponseEntry>);
impl PlChangesPosIdResponse {
pub fn new(items: Vec<PlChangesPosIdResponseEntry>) -> Self {
PlChangesPosIdResponse(items)
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PlChangesPosIdResponseEntry { pub struct PlChangesPosIdResponseEntry {
// 'cpos' // 'cpos'
@@ -90,14 +78,8 @@ pub struct PlChangesPosIdResponseEntry {
pub id: SongId, pub id: SongId,
} }
impl PlChangesPosIdResponseEntry {
pub fn new(position: SongPosition, id: SongId) -> Self {
PlChangesPosIdResponseEntry { position, id }
}
}
impl CommandResponse for PlChangesPosIdResponse { impl CommandResponse for PlChangesPosIdResponse {
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
@@ -105,7 +87,7 @@ impl CommandResponse for PlChangesPosIdResponse {
todo!() todo!()
} }
fn parse(_parts: ResponseAttributes<'_>) -> Result<Self, ResponseParserError> { fn parse(parts: ResponseAttributes<'_>) -> Result<Self, ResponseParserError> {
unimplemented!() unimplemented!()
} }
} }
-6
View File
@@ -14,12 +14,6 @@ pub struct PrioRequest {
pub window: WindowRange, pub window: WindowRange,
} }
impl PrioRequest {
pub fn new(prio: Priority, window: WindowRange) -> Self {
Self { prio, window }
}
}
impl CommandRequest for PrioRequest { impl CommandRequest for PrioRequest {
const COMMAND: &'static str = "prio"; const COMMAND: &'static str = "prio";
const MIN_ARGS: u32 = 2; const MIN_ARGS: u32 = 2;
-6
View File
@@ -14,12 +14,6 @@ pub struct PrioIdRequest {
pub songids: Vec<SongId>, pub songids: Vec<SongId>,
} }
impl PrioIdRequest {
pub fn new(prio: Priority, songids: Vec<SongId>) -> Self {
Self { prio, songids }
}
}
impl CommandRequest for PrioIdRequest { impl CommandRequest for PrioIdRequest {
const COMMAND: &'static str = "prioid"; const COMMAND: &'static str = "prioid";
const MIN_ARGS: u32 = 2; const MIN_ARGS: u32 = 2;
-9
View File
@@ -14,15 +14,6 @@ pub struct RangeIdRequest {
time_interval: TimeInterval, time_interval: TimeInterval,
} }
impl RangeIdRequest {
pub fn new(songid: SongId, time_interval: TimeInterval) -> Self {
Self {
songid,
time_interval,
}
}
}
impl CommandRequest for RangeIdRequest { impl CommandRequest for RangeIdRequest {
const COMMAND: &'static str = "rangeid"; const COMMAND: &'static str = "rangeid";
const MIN_ARGS: u32 = 2; const MIN_ARGS: u32 = 2;
-6
View File
@@ -14,12 +14,6 @@ pub struct SwapRequest {
pub songpos2: SongPosition, pub songpos2: SongPosition,
} }
impl SwapRequest {
pub fn new(songpos1: SongPosition, songpos2: SongPosition) -> Self {
Self { songpos1, songpos2 }
}
}
impl CommandRequest for SwapRequest { impl CommandRequest for SwapRequest {
const COMMAND: &'static str = "swap"; const COMMAND: &'static str = "swap";
const MIN_ARGS: u32 = 2; const MIN_ARGS: u32 = 2;
-6
View File
@@ -14,12 +14,6 @@ pub struct SwapIdRequest {
pub songid2: SongId, pub songid2: SongId,
} }
impl SwapIdRequest {
pub fn new(songid1: SongId, songid2: SongId) -> Self {
Self { songid1, songid2 }
}
}
impl CommandRequest for SwapIdRequest { impl CommandRequest for SwapIdRequest {
const COMMAND: &'static str = "swapid"; const COMMAND: &'static str = "swapid";
const MIN_ARGS: u32 = 2; const MIN_ARGS: u32 = 2;
+1 -11
View File
@@ -18,22 +18,12 @@ pub struct ConfigResponse {
pub pcre: bool, pub pcre: bool,
} }
impl ConfigResponse {
pub fn new(music_directory: String, playlist_directory: String, pcre: bool) -> Self {
ConfigResponse {
music_directory,
playlist_directory,
pcre,
}
}
}
impl CommandResponse for ConfigResponse { impl CommandResponse for ConfigResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
+1 -17
View File
@@ -16,31 +16,15 @@ pub struct Decoder {
pub mime_types: Vec<String>, pub mime_types: Vec<String>,
} }
impl Decoder {
pub fn new(plugin: String, suffixes: Vec<String>, mime_types: Vec<String>) -> Self {
Decoder {
plugin,
suffixes,
mime_types,
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct DecodersResponse(Vec<Decoder>); pub struct DecodersResponse(Vec<Decoder>);
impl DecodersResponse {
pub fn new(items: Vec<Decoder>) -> Self {
DecodersResponse(items)
}
}
impl CommandResponse for DecodersResponse { impl CommandResponse for DecodersResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
-11
View File
@@ -16,17 +16,6 @@ pub struct StickerDecRequest {
pub value: usize, pub value: usize,
} }
impl StickerDecRequest {
pub fn new(sticker_type: StickerType, uri: Uri, name: String, value: usize) -> Self {
Self {
sticker_type,
uri,
name,
value,
}
}
}
impl CommandRequest for StickerDecRequest { impl CommandRequest for StickerDecRequest {
const COMMAND: &'static str = "sticker dec"; const COMMAND: &'static str = "sticker dec";
const MIN_ARGS: u32 = 4; const MIN_ARGS: u32 = 4;
-10
View File
@@ -15,16 +15,6 @@ pub struct StickerDeleteRequest {
pub name: String, pub name: String,
} }
impl StickerDeleteRequest {
pub fn new(sticker_type: StickerType, uri: Uri, name: String) -> Self {
Self {
sticker_type,
uri,
name,
}
}
}
impl CommandRequest for StickerDeleteRequest { impl CommandRequest for StickerDeleteRequest {
const COMMAND: &'static str = "sticker delete"; const COMMAND: &'static str = "sticker delete";
const MIN_ARGS: u32 = 3; const MIN_ARGS: u32 = 3;
+1 -31
View File
@@ -18,24 +18,6 @@ pub struct StickerFindRequest {
pub window: Option<WindowRange>, pub window: Option<WindowRange>,
} }
impl StickerFindRequest {
pub fn new(
sticker_type: StickerType,
uri: Uri,
name: String,
sort: Option<Sort>,
window: Option<WindowRange>,
) -> Self {
Self {
sticker_type,
uri,
name,
sort,
window,
}
}
}
impl CommandRequest for StickerFindRequest { impl CommandRequest for StickerFindRequest {
const COMMAND: &'static str = "sticker find"; const COMMAND: &'static str = "sticker find";
const MIN_ARGS: u32 = 3; const MIN_ARGS: u32 = 3;
@@ -169,12 +151,6 @@ impl CommandRequest for StickerFindRequest {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct StickerFindResponse(Vec<StickerFindResponseEntry>); pub struct StickerFindResponse(Vec<StickerFindResponseEntry>);
impl StickerFindResponse {
pub fn new(items: Vec<StickerFindResponseEntry>) -> Self {
StickerFindResponse(items)
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct StickerFindResponseEntry { pub struct StickerFindResponseEntry {
pub uri: String, pub uri: String,
@@ -182,14 +158,8 @@ pub struct StickerFindResponseEntry {
pub value: String, pub value: String,
} }
impl StickerFindResponseEntry {
pub fn new(uri: String, name: String, value: String) -> Self {
Self { uri, name, value }
}
}
impl CommandResponse for StickerFindResponse { impl CommandResponse for StickerFindResponse {
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
-10
View File
@@ -15,16 +15,6 @@ pub struct StickerGetRequest {
pub name: String, pub name: String,
} }
impl StickerGetRequest {
pub fn new(sticker_type: StickerType, uri: Uri, name: String) -> Self {
Self {
sticker_type,
uri,
name,
}
}
}
impl CommandRequest for StickerGetRequest { impl CommandRequest for StickerGetRequest {
const COMMAND: &'static str = "sticker get"; const COMMAND: &'static str = "sticker get";
const MIN_ARGS: u32 = 3; const MIN_ARGS: u32 = 3;
-11
View File
@@ -16,17 +16,6 @@ pub struct StickerIncRequest {
pub value: usize, pub value: usize,
} }
impl StickerIncRequest {
pub fn new(sticker_type: StickerType, uri: Uri, name: String, value: usize) -> Self {
Self {
sticker_type,
uri,
name,
value,
}
}
}
impl CommandRequest for StickerIncRequest { impl CommandRequest for StickerIncRequest {
const COMMAND: &'static str = "sticker inc"; const COMMAND: &'static str = "sticker inc";
const MIN_ARGS: u32 = 4; const MIN_ARGS: u32 = 4;
+1 -13
View File
@@ -17,12 +17,6 @@ pub struct StickerListRequest {
pub uri: Uri, pub uri: Uri,
} }
impl StickerListRequest {
pub fn new(sticker_type: StickerType, uri: Uri) -> Self {
Self { sticker_type, uri }
}
}
impl CommandRequest for StickerListRequest { impl CommandRequest for StickerListRequest {
const COMMAND: &'static str = "sticker list"; const COMMAND: &'static str = "sticker list";
const MIN_ARGS: u32 = 2; const MIN_ARGS: u32 = 2;
@@ -74,18 +68,12 @@ impl CommandRequest for StickerListRequest {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct StickerListResponse(HashMap<String, String>); pub struct StickerListResponse(HashMap<String, String>);
impl StickerListResponse {
pub fn new(map: HashMap<String, String>) -> Self {
StickerListResponse(map)
}
}
impl CommandResponse for StickerListResponse { impl CommandResponse for StickerListResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
-11
View File
@@ -16,17 +16,6 @@ pub struct StickerSetRequest {
pub value: String, pub value: String,
} }
impl StickerSetRequest {
pub fn new(sticker_type: StickerType, uri: Uri, name: String, value: String) -> Self {
Self {
sticker_type,
uri,
name,
value,
}
}
}
impl CommandRequest for StickerSetRequest { impl CommandRequest for StickerSetRequest {
const COMMAND: &'static str = "sticker set"; const COMMAND: &'static str = "sticker set";
const MIN_ARGS: u32 = 4; const MIN_ARGS: u32 = 4;
+1 -13
View File
@@ -14,12 +14,6 @@ pub struct StickerNamesTypes;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct StickerNamesTypesRequest(Option<StickerType>); pub struct StickerNamesTypesRequest(Option<StickerType>);
impl StickerNamesTypesRequest {
pub fn new(sticker_type: Option<StickerType>) -> Self {
Self(sticker_type)
}
}
impl CommandRequest for StickerNamesTypesRequest { impl CommandRequest for StickerNamesTypesRequest {
const COMMAND: &'static str = "stickernamestypes"; const COMMAND: &'static str = "stickernamestypes";
const MIN_ARGS: u32 = 0; const MIN_ARGS: u32 = 0;
@@ -65,18 +59,12 @@ impl CommandRequest for StickerNamesTypesRequest {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct StickerNamesTypesResponse(HashMap<String, Vec<String>>); pub struct StickerNamesTypesResponse(HashMap<String, Vec<String>>);
impl StickerNamesTypesResponse {
pub fn new(map: HashMap<String, Vec<String>>) -> Self {
StickerNamesTypesResponse(map)
}
}
impl CommandResponse for StickerNamesTypesResponse { impl CommandResponse for StickerNamesTypesResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
@@ -20,12 +20,6 @@ pub struct ListPlaylistRequest {
range: Option<WindowRange>, range: Option<WindowRange>,
} }
impl ListPlaylistRequest {
pub fn new(name: PlaylistName, range: Option<WindowRange>) -> Self {
Self { name, range }
}
}
impl CommandRequest for ListPlaylistRequest { impl CommandRequest for ListPlaylistRequest {
const COMMAND: &'static str = "listplaylist"; const COMMAND: &'static str = "listplaylist";
const MIN_ARGS: u32 = 1; const MIN_ARGS: u32 = 1;
@@ -15,12 +15,6 @@ pub struct ListPlaylistInfoRequest {
range: Option<WindowRange>, range: Option<WindowRange>,
} }
impl ListPlaylistInfoRequest {
pub fn new(name: PlaylistName, range: Option<WindowRange>) -> Self {
Self { name, range }
}
}
impl CommandRequest for ListPlaylistInfoRequest { impl CommandRequest for ListPlaylistInfoRequest {
const COMMAND: &'static str = "listplaylistinfo"; const COMMAND: &'static str = "listplaylistinfo";
const MIN_ARGS: u32 = 1; const MIN_ARGS: u32 = 1;
@@ -69,22 +63,16 @@ impl CommandRequest for ListPlaylistInfoRequest {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ListPlaylistInfoResponse(Vec<DbSongInfo>); pub struct ListPlaylistInfoResponse(Vec<DbSongInfo>);
impl ListPlaylistInfoResponse {
pub fn new(items: Vec<DbSongInfo>) -> Self {
ListPlaylistInfoResponse(items)
}
}
impl CommandResponse for ListPlaylistInfoResponse { impl CommandResponse for ListPlaylistInfoResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
fn parse(_parts: ResponseAttributes<'_>) -> Result<Self, ResponseParserError> { fn parse(parts: ResponseAttributes<'_>) -> Result<Self, ResponseParserError> {
unimplemented!() unimplemented!()
} }
} }
+1 -16
View File
@@ -13,12 +13,6 @@ empty_command_request!(ListPlaylists, "listplaylists");
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ListPlaylistsResponse(Vec<ListPlaylistsResponseEntry>); pub struct ListPlaylistsResponse(Vec<ListPlaylistsResponseEntry>);
impl ListPlaylistsResponse {
pub fn new(items: Vec<ListPlaylistsResponseEntry>) -> Self {
ListPlaylistsResponse(items)
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ListPlaylistsResponseEntry { pub struct ListPlaylistsResponseEntry {
pub playlist: PlaylistName, pub playlist: PlaylistName,
@@ -26,21 +20,12 @@ pub struct ListPlaylistsResponseEntry {
pub last_modified: Option<String>, pub last_modified: Option<String>,
} }
impl ListPlaylistsResponseEntry {
pub fn new(playlist: PlaylistName, last_modified: Option<String>) -> Self {
ListPlaylistsResponseEntry {
playlist,
last_modified,
}
}
}
impl CommandResponse for ListPlaylistsResponse { impl CommandResponse for ListPlaylistsResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
-14
View File
@@ -15,20 +15,6 @@ pub struct LoadRequest {
position: Option<SongPosition>, position: Option<SongPosition>,
} }
impl LoadRequest {
pub fn new(
name: PlaylistName,
range: Option<WindowRange>,
position: Option<SongPosition>,
) -> Self {
Self {
name,
range,
position,
}
}
}
impl CommandRequest for LoadRequest { impl CommandRequest for LoadRequest {
const COMMAND: &'static str = "load"; const COMMAND: &'static str = "load";
const MIN_ARGS: u32 = 1; const MIN_ARGS: u32 = 1;
@@ -15,16 +15,6 @@ pub struct PlaylistAddRequest {
pub position: Option<SongPosition>, pub position: Option<SongPosition>,
} }
impl PlaylistAddRequest {
pub fn new(playlist_name: PlaylistName, uri: Uri, position: Option<SongPosition>) -> Self {
Self {
playlist_name,
uri,
position,
}
}
}
impl CommandRequest for PlaylistAddRequest { impl CommandRequest for PlaylistAddRequest {
const COMMAND: &'static str = "playlistadd"; const COMMAND: &'static str = "playlistadd";
const MIN_ARGS: u32 = 2; const MIN_ARGS: u32 = 2;
@@ -14,15 +14,6 @@ pub struct PlaylistDeleteRequest {
pub position: OneOrRange, pub position: OneOrRange,
} }
impl PlaylistDeleteRequest {
pub fn new(playlist_name: PlaylistName, position: OneOrRange) -> Self {
Self {
playlist_name,
position,
}
}
}
impl CommandRequest for PlaylistDeleteRequest { impl CommandRequest for PlaylistDeleteRequest {
const COMMAND: &'static str = "playlistdelete"; const COMMAND: &'static str = "playlistdelete";
const MIN_ARGS: u32 = 2; const MIN_ARGS: u32 = 2;
@@ -18,18 +18,12 @@ pub struct PlaylistLengthResponse {
pub playtime: u64, pub playtime: u64,
} }
impl PlaylistLengthResponse {
pub fn new(songs: u64, playtime: u64) -> Self {
PlaylistLengthResponse { songs, playtime }
}
}
impl CommandResponse for PlaylistLengthResponse { impl CommandResponse for PlaylistLengthResponse {
fn into_response_enum(self) -> crate::Response { fn into_response_enum(self) -> crate::Response {
todo!() todo!()
} }
fn from_response_enum(_response: crate::Response) -> Option<Self> { fn from_response_enum(response: crate::Response) -> Option<Self> {
todo!() todo!()
} }
@@ -15,16 +15,6 @@ pub struct PlaylistMoveRequest {
pub to: SongPosition, pub to: SongPosition,
} }
impl PlaylistMoveRequest {
pub fn new(playlist_name: PlaylistName, from: Option<OneOrRange>, to: SongPosition) -> Self {
Self {
playlist_name,
from,
to,
}
}
}
impl CommandRequest for PlaylistMoveRequest { impl CommandRequest for PlaylistMoveRequest {
const COMMAND: &'static str = "playlistmove"; const COMMAND: &'static str = "playlistmove";
const MIN_ARGS: u32 = 2; const MIN_ARGS: u32 = 2;
-6
View File
@@ -13,12 +13,6 @@ pub struct RenameRequest {
pub new_name: String, pub new_name: String,
} }
impl RenameRequest {
pub fn new(old_name: String, new_name: String) -> Self {
Self { old_name, new_name }
}
}
impl CommandRequest for RenameRequest { impl CommandRequest for RenameRequest {
const COMMAND: &'static str = "rename"; const COMMAND: &'static str = "rename";
const MIN_ARGS: u32 = 2; const MIN_ARGS: u32 = 2;
-9
View File
@@ -14,15 +14,6 @@ pub struct SaveRequest {
pub mode: Option<SaveMode>, pub mode: Option<SaveMode>,
} }
impl SaveRequest {
pub fn new(playlist_name: PlaylistName, mode: Option<SaveMode>) -> Self {
Self {
playlist_name,
mode,
}
}
}
impl CommandRequest for SaveRequest { impl CommandRequest for SaveRequest {
const COMMAND: &'static str = "save"; const COMMAND: &'static str = "save";
const MIN_ARGS: u32 = 2; const MIN_ARGS: u32 = 2;
@@ -16,16 +16,6 @@ pub struct SearchPlaylistRequest {
pub range: Option<WindowRange>, pub range: Option<WindowRange>,
} }
impl SearchPlaylistRequest {
pub fn new(name: PlaylistName, filter: Filter, range: Option<WindowRange>) -> Self {
Self {
name,
filter,
range,
}
}
}
impl CommandRequest for SearchPlaylistRequest { impl CommandRequest for SearchPlaylistRequest {
const COMMAND: &'static str = "searchplaylist"; const COMMAND: &'static str = "searchplaylist";
const MIN_ARGS: u32 = 2; const MIN_ARGS: u32 = 2;
+1
View File
@@ -3,6 +3,7 @@ use std::fmt::Display;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use thiserror::Error; use thiserror::Error;
// See https://github.com/MusicPlayerDaemon/MPD/blob/7774c3369e1484dc5dec6d7d9572e0a57e9c5302/src/command/AllCommands.cxx#L67-L209
pub type Response = Result<(), MpdError>; pub type Response = Result<(), MpdError>;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
+89 -81
View File
@@ -69,97 +69,105 @@ impl<'a> Iterator for ResponseAttributes<'a> {
type Item = Result<(&'a str, GenericResponseValue<'a>), ResponseParserError>; type Item = Result<(&'a str, GenericResponseValue<'a>), ResponseParserError>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
loop { if self.cursor >= self.bytestring.len() {
if self.cursor >= self.bytestring.len() { return Some(Err(ResponseParserError::UnexpectedEOF));
}
if self.bytestring[self.cursor..].starts_with(b"OK") {
return None;
}
let remaining = &self.bytestring[self.cursor..];
let newline_pos = remaining
.iter()
.position(|&b| b == b'\n')
.unwrap_or(remaining.len());
let line = &remaining[..newline_pos];
// Skip empty lines
if line.is_empty() {
self.cursor += newline_pos + 1;
return self.next();
}
// NOTE: it is important that this happens before any None returns,
// so that the iterator advances despite errors.
self.cursor += newline_pos + 1;
let mut keyval = line.splitn(2, |&b| b == b':');
let key_bytes = keyval.next()?;
// TODO: should this be a proper runtime error?
debug_assert!(!key_bytes.is_empty());
debug_assert!(std::str::from_utf8(key_bytes).is_ok());
let key = std::str::from_utf8(key_bytes).ok()?;
// In the case of binary data, the following value will be the byte count
// in decimal, and the actual binary data will follow in the next N bytes,
// followed by a newline.
//
// We parse the number and assign the binary data to the "binary" key.
if key == "binary" {
let byte_count = match keyval.next() {
Some(count) => count.trim_ascii_start(),
None => {
// TODO: throw more specific error
return Some(Err(ResponseParserError::UnexpectedEOF));
}
};
let byte_count_str = match std::str::from_utf8(byte_count) {
Ok(s) => s,
Err(_) => {
// TODO: throw more specific error
return Some(Err(ResponseParserError::SyntaxError(
0,
"Invalid byte count".to_string(),
)));
}
};
let byte_count: usize = match byte_count_str.parse() {
Ok(n) => n,
Err(_) => {
// TODO: throw more specific error
return Some(Err(ResponseParserError::SyntaxError(
0,
"Invalid byte count".to_string(),
)));
}
};
let value_start = self.cursor;
let value_end = self.cursor + byte_count;
if value_end > self.bytestring.len() {
return Some(Err(ResponseParserError::UnexpectedEOF)); return Some(Err(ResponseParserError::UnexpectedEOF));
} }
let value_bytes = &self.bytestring[value_start..value_end];
if self.bytestring[self.cursor..].starts_with(b"OK") { debug_assert!(
return None; self.bytestring[value_end..]
} .iter()
.next()
.is_none_or(|&b| b == b'\n')
);
let remaining = &self.bytestring[self.cursor..]; // Skip the binary data and the following newline
let newline_pos = remaining self.cursor = value_end + 1;
.iter()
.position(|&b| b == b'\n')
.unwrap_or(remaining.len());
let line = &remaining[..newline_pos]; Some(Ok((key, GenericResponseValue::Binary(value_bytes))))
} else {
let value_bytes = match keyval.next() {
Some(v) => v.trim_ascii_start(),
None => b"",
};
// TODO: this should be a proper runtime error, the specification
// declares that all string values are UTF-8.
debug_assert!(std::str::from_utf8(value_bytes).is_ok());
let value_str = std::str::from_utf8(value_bytes).ok()?;
// NOTE: it is important that this happens before any further None returns, Some(Ok((key, GenericResponseValue::Text(value_str))))
// so that the iterator advances despite errors.
self.cursor += newline_pos + 1;
if line.is_empty() {
continue;
}
return Some(parse_line(line, self));
} }
} }
} }
fn parse_line<'a>(
line: &'a [u8],
state: &mut ResponseAttributes<'a>,
) -> Result<(&'a str, GenericResponseValue<'a>), ResponseParserError> {
let mut parts = line.splitn(2, |&b| b == b':');
let key = parts
.next()
.filter(|k| !k.is_empty())
.and_then(|k| std::str::from_utf8(k).ok())
.ok_or_else(|| ResponseParserError::SyntaxError(0, "Invalid key".into()))?;
match key {
"binary" => parse_binary(parts.next(), state).map(|v| (key, v)),
_ => {
let value = parts.next().unwrap_or(b"").trim_ascii_start();
let text = std::str::from_utf8(value)
.map_err(|_| ResponseParserError::SyntaxError(0, "Invalid UTF-8".into()))?;
Ok((key, GenericResponseValue::Text(text)))
}
}
}
fn parse_binary<'a>(
count_bytes: Option<&[u8]>,
state: &mut ResponseAttributes<'a>,
) -> Result<GenericResponseValue<'a>, ResponseParserError> {
// In the case of binary data, the following value will be the byte count
// in decimal, and the actual binary data will follow in the next N bytes,
// followed by a newline.
//
// We parse the number and assign the binary data to the "binary" key.
let count = count_bytes
.map(|b| b.trim_ascii_start())
.and_then(|b| std::str::from_utf8(b).ok())
.and_then(|s| s.parse::<usize>().ok())
.ok_or_else(|| ResponseParserError::SyntaxError(0, "Invalid byte count".into()))?;
let start = state.cursor;
let end = start + count;
if end > state.bytestring.len() {
return Err(ResponseParserError::UnexpectedEOF);
}
let bytes = &state.bytestring[start..end];
if state.bytestring.get(end).is_some_and(|&b| b != b'\n') {
return Err(ResponseParserError::SyntaxError(
0,
"Missing newline".into(),
));
}
state.cursor = end + 1;
Ok(GenericResponseValue::Binary(bytes))
}
impl<'a> From<ResponseAttributes<'a>> impl<'a> From<ResponseAttributes<'a>>
for Result<HashMap<&'a str, GenericResponseValue<'a>>, ResponseParserError> for Result<HashMap<&'a str, GenericResponseValue<'a>>, ResponseParserError>
{ {