2 Commits

Author SHA1 Message Date
f674b0b0b1 WIP 2025-02-25 12:17:03 +01:00
493995c1f2 common/types: add db selection print types 2025-02-25 12:17:03 +01:00
81 changed files with 348 additions and 122 deletions

View File

@@ -83,8 +83,8 @@ jobs:
target: ${{ gitea.ref_name }}/coverage/
username: gitea-web
ssh-key: ${{ secrets.WEB_SYNC_SSH_KEY }}
host: pages.pvv.ntnu.no
known-hosts: "pages.pvv.ntnu.no ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH2QjfFB+city1SYqltkVqWACfo1j37k+oQQfj13mtgg"
host: bekkalokk.pvv.ntnu.no
known-hosts: "bekkalokk.pvv.ntnu.no ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEI6VSaDrMG8+flg4/AeHlAFIen8RUzWh6URQKqFegSx"
docs:
runs-on: ubuntu-latest
@@ -107,6 +107,6 @@ jobs:
target: ${{ gitea.ref_name }}/docs/
username: gitea-web
ssh-key: ${{ secrets.WEB_SYNC_SSH_KEY }}
host: pages.pvv.ntnu.no
known-hosts: "pages.pvv.ntnu.no ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH2QjfFB+city1SYqltkVqWACfo1j37k+oQQfj13mtgg"
host: bekkalokk.pvv.ntnu.no
known-hosts: "bekkalokk.pvv.ntnu.no ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEI6VSaDrMG8+flg4/AeHlAFIen8RUzWh6URQKqFegSx"

30
Cargo.lock generated
View File

@@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
version = 3
[[package]]
name = "diff"
@@ -19,9 +19,9 @@ dependencies = [
[[package]]
name = "indoc"
version = "2.0.6"
version = "2.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd"
checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5"
[[package]]
name = "pretty_assertions"
@@ -35,36 +35,36 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.95"
version = "1.0.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
dependencies = [
"proc-macro2",
]
[[package]]
name = "serde"
version = "1.0.219"
version = "1.0.210"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.219"
version = "1.0.210"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
dependencies = [
"proc-macro2",
"quote",
@@ -73,9 +73,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.104"
version = "2.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
checksum = "83540f837a8afc019423a8edb95b52a8effe46957ee402287f4292fae35be021"
dependencies = [
"proc-macro2",
"quote",
@@ -84,9 +84,9 @@ dependencies = [
[[package]]
name = "unicode-ident"
version = "1.0.18"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
[[package]]
name = "yansi"

View File

@@ -7,12 +7,12 @@ authors = [
description = "A rust implementation of the mpd protocol, both client and serverside"
repository = "https://git.pvv.ntnu.no/Grzegorz/empidee"
documentation = "https://pages.pvv.ntnu.no/Grzegorz/empidee/main/docs/empidee/"
edition = "2024"
rust-version = "1.85.0"
edition = "2021"
rust-version = "1.83.0"
[dependencies]
serde = { version = "1.0.219", features = ["derive"] }
serde = { version = "1.0.210", features = ["derive"] }
[dev-dependencies]
indoc = "2.0.6"
indoc = "2.0.5"
pretty_assertions = "1.4.1"

12
flake.lock generated
View File

@@ -2,11 +2,11 @@
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1753939845,
"narHash": "sha256-K2ViRJfdVGE8tpJejs8Qpvvejks1+A4GQej/lBk5y7I=",
"lastModified": 1739866667,
"narHash": "sha256-EO1ygNKZlsAC9avfcwHkKGMsmipUk1Uc0TbrEZpkn64=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "94def634a20494ee057c76998843c015909d6311",
"rev": "73cf49b8ad837ade2de76f87eb53fc85ed5d4680",
"type": "github"
},
"original": {
@@ -29,11 +29,11 @@
]
},
"locked": {
"lastModified": 1754189623,
"narHash": "sha256-fstu5eb30UYwsxow0aQqkzxNxGn80UZjyehQVNVHuBk=",
"lastModified": 1740277845,
"narHash": "sha256-NNU0CdiaSbAeZ8tpDG4aFi9qtcdlItRvk8Xns9oBrVU=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "c582ff7f0d8a7ea689ae836dfb1773f1814f472a",
"rev": "f933070c29f9c1c5457447a51903f27f76ebb519",
"type": "github"
},
"original": {

View File

@@ -36,7 +36,6 @@
default = pkgs.mkShell {
nativeBuildInputs = [
toolchain
pkgs.cargo-edit
];
RUST_SRC_PATH = "${toolchain}/lib/rustlib/src/rust/library";

View File

@@ -1 +0,0 @@
style_edition = "2024"

View File

@@ -1,8 +1,8 @@
use serde::{Deserialize, Serialize};
use crate::commands::{
Command, Request, RequestParserResult, ResponseAttributes, ResponseParserError,
expect_property_type,
expect_property_type, Command, Request, RequestParserResult, ResponseAttributes,
ResponseParserError,
};
pub struct Channels;

View File

@@ -1,8 +1,8 @@
use serde::{Deserialize, Serialize};
use crate::commands::{
Command, Request, RequestParserResult, ResponseAttributes, ResponseParserError,
expect_property_type,
expect_property_type, Command, Request, RequestParserResult, ResponseAttributes,
ResponseParserError,
};
pub struct ReadMessages;

View File

@@ -1,6 +1,6 @@
use crate::{
Request,
commands::{Command, RequestParserResult, ResponseAttributes, ResponseParserError},
Request,
};
pub struct Protocol;

View File

@@ -1,6 +1,6 @@
use crate::{
Request,
commands::{Command, RequestParserResult, ResponseAttributes, ResponseParserError},
Request,
};
pub struct ProtocolAll;

View File

@@ -1,6 +1,6 @@
use crate::{
Request,
commands::{Command, RequestParserResult, ResponseAttributes, ResponseParserError},
Request,
};
pub struct ProtocolAvailable;

View File

@@ -1,6 +1,6 @@
use crate::{
Request,
commands::{Command, RequestParserResult, ResponseAttributes, ResponseParserError},
Request,
};
pub struct ProtocolClear;

View File

@@ -1,8 +1,8 @@
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
Request,
};
pub struct ProtocolDisable;

View File

@@ -1,8 +1,8 @@
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
Request,
};
pub struct ProtocolEnable;

View File

@@ -30,7 +30,7 @@ impl Command for TagTypes {
GenericResponseValue::Binary(_) => {
return Err(ResponseParserError::UnexpectedPropertyType(
"tagtype", "Binary",
));
))
}
};

View File

@@ -1,6 +1,6 @@
use crate::{
Request,
commands::{Command, RequestParserResult, ResponseAttributes, ResponseParserError},
Request,
};
pub struct TagTypesAll;

View File

@@ -1,6 +1,6 @@
use crate::{
Request,
commands::{Command, RequestParserResult, ResponseAttributes, ResponseParserError},
Request,
};
pub struct TagTypesAvailable;

View File

@@ -1,6 +1,6 @@
use crate::{
Request,
commands::{Command, RequestParserResult, ResponseAttributes, ResponseParserError},
Request,
};
pub struct TagTypesClear;

View File

@@ -1,8 +1,8 @@
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
Request,
};
pub struct TagTypesDisable;

View File

@@ -1,8 +1,8 @@
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
Request,
};
pub struct TagTypesEnable;

View File

@@ -1,8 +1,8 @@
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
Request,
};
pub struct TagTypesReset;

View File

@@ -1,6 +1,6 @@
use crate::{
Request,
commands::{Command, RequestParserResult, ResponseAttributes, ResponseParserError},
Request,
};
pub struct ListMounts;

View File

@@ -1,6 +1,6 @@
use crate::{
Request,
commands::{Command, RequestParserResult, ResponseAttributes, ResponseParserError},
Request,
};
pub struct ListNeighbors;

View File

@@ -1,8 +1,8 @@
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
Request,
};
pub struct Mount;

View File

@@ -1,8 +1,8 @@
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
Request,
};
pub struct Unmount;

View File

@@ -2,8 +2,8 @@ use std::collections::HashMap;
use crate::{
commands::{
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
ResponseParserError, get_and_parse_property, get_property,
get_and_parse_property, get_property, Command, Request, RequestParserError,
RequestParserResult, ResponseAttributes, ResponseParserError,
},
common::Offset,
};

View File

@@ -2,8 +2,8 @@ use std::collections::HashMap;
use crate::{
commands::{
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
ResponseParserError, get_and_parse_property,
get_and_parse_property, Command, Request, RequestParserError, RequestParserResult,
ResponseAttributes, ResponseParserError,
},
filter::parse_filter,
};

View File

@@ -46,6 +46,7 @@ impl Command for Find {
fn parse_response(
parts: ResponseAttributes<'_>,
) -> Result<Self::Response, ResponseParserError> {
// db_selection_print
unimplemented!()
}
}

View File

@@ -1,8 +1,8 @@
use std::collections::HashMap;
use crate::commands::{
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
ResponseParserError, get_and_parse_property,
get_and_parse_property, Command, Request, RequestParserError, RequestParserResult,
ResponseAttributes, ResponseParserError,
};
pub struct GetFingerprint;

View File

@@ -1,7 +1,7 @@
use crate::{
commands::{
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
ResponseParserError, expect_property_type,
expect_property_type, Command, Request, RequestParserError, RequestParserResult,
ResponseAttributes, ResponseParserError,
},
filter::parse_filter,
};

View File

@@ -2,12 +2,11 @@ use crate::commands::{
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
ResponseParserError,
};
use crate::common::DbSelectionPrintResponse;
pub struct ListAllInfo;
// TODO: This is supposed to be a tree-like structure, with directories containing files and playlists
// in addition to the metadata of each entry
pub type ListAllInfoResponse = Vec<String>;
pub type ListAllInfoResponse = Vec<DbSelectionPrintResponse>;
impl Command for ListAllInfo {
type Response = ListAllInfoResponse;
@@ -30,6 +29,6 @@ impl Command for ListAllInfo {
fn parse_response(
parts: ResponseAttributes<'_>,
) -> Result<Self::Response, ResponseParserError> {
unimplemented!()
DbSelectionPrintResponse::parse(parts)
}
}

View File

@@ -29,6 +29,7 @@ impl Command for ListFiles {
fn parse_response(
parts: ResponseAttributes<'_>,
) -> Result<Self::Response, ResponseParserError> {
// db_selection_print
unimplemented!()
}
}

View File

@@ -29,6 +29,7 @@ impl Command for LsInfo {
fn parse_response(
parts: ResponseAttributes<'_>,
) -> Result<Self::Response, ResponseParserError> {
// db_selection_print
unimplemented!()
}
}

View File

@@ -2,8 +2,8 @@ use std::collections::HashMap;
use crate::{
commands::{
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
ResponseParserError, get_and_parse_property, get_optional_property, get_property,
get_and_parse_property, get_optional_property, get_property, Command, Request,
RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
common::Offset,
};

View File

@@ -1,8 +1,8 @@
use std::collections::HashMap;
use crate::commands::{
Command, Request, RequestParserResult, ResponseAttributes, ResponseParserError,
get_and_parse_property,
get_and_parse_property, Command, Request, RequestParserResult, ResponseAttributes,
ResponseParserError,
};
pub struct Rescan;

View File

@@ -46,6 +46,7 @@ impl Command for Search {
fn parse_response(
parts: ResponseAttributes<'_>,
) -> Result<Self::Response, ResponseParserError> {
// db_selection_print
unimplemented!()
}
}

View File

@@ -2,8 +2,8 @@ use std::collections::HashMap;
use crate::{
commands::{
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
ResponseParserError, get_and_parse_property,
get_and_parse_property, Command, Request, RequestParserError, RequestParserResult,
ResponseAttributes, ResponseParserError,
},
filter::parse_filter,
};

View File

@@ -1,8 +1,8 @@
use std::collections::HashMap;
use crate::commands::{
Command, Request, RequestParserResult, ResponseAttributes, ResponseParserError,
get_and_parse_property,
get_and_parse_property, Command, Request, RequestParserResult, ResponseAttributes,
ResponseParserError,
};
pub struct Update;

View File

@@ -1,6 +1,6 @@
use crate::commands::{
Command, Request, RequestParserResult, ResponseAttributes, ResponseParserError,
expect_property_type,
expect_property_type, Command, Request, RequestParserResult, ResponseAttributes,
ResponseParserError,
};
pub struct ListPartitions;

View File

@@ -2,8 +2,8 @@ use std::collections::HashMap;
use crate::{
commands::{
Command, Request, RequestParserResult, ResponseAttributes, ResponseParserError,
get_and_parse_property,
get_and_parse_property, Command, Request, RequestParserResult, ResponseAttributes,
ResponseParserError,
},
common::VolumeValue,
};

View File

@@ -4,8 +4,8 @@ use serde::{Deserialize, Serialize};
use crate::{
commands::{
Command, Request, RequestParserResult, ResponseAttributes, ResponseParserError,
get_property,
get_property, Command, Request, RequestParserResult, ResponseAttributes,
ResponseParserError,
},
common::ReplayGainModeMode,
};

View File

@@ -3,8 +3,8 @@ use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use crate::commands::{
Command, Request, RequestParserResult, ResponseAttributes, ResponseParserError,
get_and_parse_optional_property, get_and_parse_property,
get_and_parse_optional_property, get_and_parse_property, Command, Request, RequestParserResult,
ResponseAttributes, ResponseParserError,
};
pub struct Stats;

View File

@@ -6,9 +6,9 @@ use serde::{Deserialize, Serialize};
use crate::common::{Audio, BoolOrOneshot, SongId, SongPosition};
use crate::commands::{
get_and_parse_optional_property, get_and_parse_property, get_optional_property, get_property,
Command, GenericResponseValue, Request, RequestParserResult, ResponseAttributes,
ResponseParserError, get_and_parse_optional_property, get_and_parse_property,
get_optional_property, get_property,
ResponseParserError,
};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]

View File

@@ -1,7 +1,7 @@
use crate::{
commands::{
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
ResponseParserError, get_next_and_parse_property,
get_next_and_parse_property, Command, Request, RequestParserError, RequestParserResult,
ResponseAttributes, ResponseParserError,
},
common::{SongId, SongPosition},
};

View File

@@ -1,8 +1,8 @@
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
Request,
};
pub struct AddTagId;

View File

@@ -1,8 +1,8 @@
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
Request,
};
pub struct ClearTagId;

View File

@@ -1,11 +1,11 @@
use std::str::FromStr;
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
common::OneOrRange,
Request,
};
pub struct Delete;

View File

@@ -1,8 +1,8 @@
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
Request,
};
pub struct DeleteId;

View File

@@ -1,8 +1,8 @@
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
Request,
};
pub struct Move;

View File

@@ -1,8 +1,8 @@
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
Request,
};
pub struct MoveId;

View File

@@ -1,6 +1,6 @@
use crate::{
Request,
commands::{Command, RequestParserResult, ResponseAttributes, ResponseParserError},
Request,
};
pub struct Playlist;

View File

@@ -1,9 +1,9 @@
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
filter::parse_filter,
Request,
};
pub struct PlaylistFind;

View File

@@ -1,8 +1,8 @@
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
Request,
};
pub struct PlaylistId;

View File

@@ -1,8 +1,8 @@
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
Request,
};
pub struct PlaylistInfo;

View File

@@ -1,9 +1,9 @@
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
filter::parse_filter,
Request,
};
pub struct PlaylistSearch;

View File

@@ -1,8 +1,8 @@
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
Request,
};
pub struct PlChanges;

View File

@@ -1,8 +1,8 @@
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
Request,
};
pub struct PlChangesPosId;

View File

@@ -1,8 +1,8 @@
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
Request,
};
pub struct Prio;

View File

@@ -1,8 +1,8 @@
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
Request,
};
pub struct PrioId;

View File

@@ -1,8 +1,8 @@
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
Request,
};
pub struct RangeId;

View File

@@ -1,8 +1,8 @@
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
Request,
};
pub struct Shuffle;

View File

@@ -1,8 +1,8 @@
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
Request,
};
pub struct Swap;

View File

@@ -1,8 +1,8 @@
use crate::{
Request,
commands::{
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
},
Request,
};
pub struct SwapId;

View File

@@ -30,7 +30,7 @@ impl Command for Commands {
GenericResponseValue::Binary(_) => {
return Err(ResponseParserError::UnexpectedPropertyType(
"handler", "Binary",
));
))
}
};
result.push(value.to_string());

View File

@@ -1,8 +1,8 @@
use std::collections::HashMap;
use crate::commands::{
Command, Request, RequestParserResult, ResponseAttributes, ResponseParserError,
get_and_parse_property, get_property,
get_and_parse_property, get_property, Command, Request, RequestParserResult,
ResponseAttributes, ResponseParserError,
};
pub struct Config;

View File

@@ -30,7 +30,7 @@ impl Command for NotCommands {
GenericResponseValue::Binary(_) => {
return Err(ResponseParserError::UnexpectedPropertyType(
"handler", "Binary",
));
))
}
};
result.push(value.to_string());

View File

@@ -30,7 +30,7 @@ impl Command for UrlHandlers {
GenericResponseValue::Binary(_) => {
return Err(ResponseParserError::UnexpectedPropertyType(
"handler", "Binary",
));
))
}
};
url_handlers.push(value.to_string());

View File

@@ -87,7 +87,7 @@ impl Command for StickerFind {
let uri = match uri.1 {
GenericResponseValue::Text(s) => s.to_string(),
GenericResponseValue::Binary(_) => {
return Err(ResponseParserError::UnexpectedPropertyType(uri.0, "Binary"));
return Err(ResponseParserError::UnexpectedPropertyType(uri.0, "Binary"))
}
};
@@ -96,7 +96,7 @@ impl Command for StickerFind {
GenericResponseValue::Binary(_) => {
return Err(ResponseParserError::UnexpectedPropertyType(
"sticker", "Binary",
));
))
}
};

View File

@@ -1,6 +1,6 @@
use crate::commands::{
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
ResponseParserError, get_next_property,
get_next_property, Command, Request, RequestParserError, RequestParserResult,
ResponseAttributes, ResponseParserError,
};
pub struct StickerGet;

View File

@@ -1,6 +1,6 @@
use crate::commands::{
Command, Request, RequestParserResult, ResponseAttributes, ResponseParserError,
expect_property_type,
expect_property_type, Command, Request, RequestParserResult, ResponseAttributes,
ResponseParserError,
};
pub struct StickerNames;

View File

@@ -39,7 +39,7 @@ impl Command for StickerNamesTypes {
GenericResponseValue::Binary(_) => {
return Err(ResponseParserError::UnexpectedPropertyType(
"name", "Binary",
));
))
}
};
@@ -48,7 +48,7 @@ impl Command for StickerNamesTypes {
GenericResponseValue::Binary(_) => {
return Err(ResponseParserError::UnexpectedPropertyType(
"type", "Binary",
));
))
}
};

View File

@@ -1,6 +1,6 @@
use crate::commands::{
Command, Request, RequestParserResult, ResponseAttributes, ResponseParserError,
expect_property_type,
expect_property_type, Command, Request, RequestParserResult, ResponseAttributes,
ResponseParserError,
};
pub struct StickerTypes;

View File

@@ -16,6 +16,8 @@ impl Command for ListPlaylists {
fn parse_response(
parts: ResponseAttributes<'_>,
) -> Result<Self::Response, ResponseParserError> {
// playlist: string
// Last-Modified: mtime?
unimplemented!()
}
}

View File

@@ -1,8 +1,8 @@
use std::collections::HashMap;
use crate::commands::{
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
ResponseParserError, get_and_parse_property,
get_and_parse_property, Command, Request, RequestParserError, RequestParserResult,
ResponseAttributes, ResponseParserError,
};
pub struct PlaylistLength;

View File

@@ -1,6 +1,10 @@
mod absolute_relative_song_position;
mod audio;
mod bool_or_oneshot;
mod db_directory_info;
mod db_playlist_info;
mod db_selection_print;
mod db_song_info;
mod group_type;
mod one_or_range;
mod replay_gain_mode_mode;
@@ -15,6 +19,10 @@ mod window_range;
pub use absolute_relative_song_position::AbsouluteRelativeSongPosition;
pub use audio::Audio;
pub use bool_or_oneshot::BoolOrOneshot;
pub use db_directory_info::DbDirectoryInfo;
pub use db_playlist_info::DbPlaylistInfo;
pub use db_selection_print::DbSelectionPrintResponse;
pub use db_song_info::DbSongInfo;
pub use group_type::GroupType;
pub use one_or_range::OneOrRange;
pub use replay_gain_mode_mode::ReplayGainModeMode;

View File

@@ -0,0 +1,30 @@
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use crate::commands::{
get_optional_property, get_property, ResponseAttributes, ResponseParserError,
};
use super::Path;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct DbDirectoryInfo {
pub directory: Path,
// TODO: parse this
pub last_modified: Option<String>,
}
impl DbDirectoryInfo {
pub fn parse(parts: ResponseAttributes<'_>) -> Result<Self, ResponseParserError<'_>> {
let parts: HashMap<_, _> = parts.into();
let directory = get_property!(parts, "directory", Text).to_owned();
let last_modified =
get_optional_property!(parts, "Last-Modified", Text).map(|s| s.to_owned());
Ok(DbDirectoryInfo {
directory,
last_modified,
})
}
}

View File

@@ -0,0 +1,31 @@
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use crate::commands::{
get_optional_property, get_property, ResponseAttributes, ResponseParserError,
};
use super::PlaylistName;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct DbPlaylistInfo {
pub playlist: PlaylistName,
// TODO: parse this
pub last_modified: Option<String>,
}
impl DbPlaylistInfo {
pub fn parse(parts: ResponseAttributes<'_>) -> Result<Self, ResponseParserError<'_>> {
let parts: HashMap<_, _> = parts.into();
let playlist = get_property!(parts, "playlist", Text).to_owned();
let last_modified =
get_optional_property!(parts, "Last-Modified", Text).map(|s| s.to_owned());
Ok(DbPlaylistInfo {
playlist,
last_modified,
})
}
}

View File

@@ -0,0 +1,86 @@
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use crate::commands::{ResponseAttributes, ResponseParserError};
use super::{DbDirectoryInfo, DbPlaylistInfo, DbSongInfo};
// TODO: transform to a tree structure?
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum DbSelectionPrintResponse {
Directory(DbDirectoryInfo),
Song(DbSongInfo),
Playlist(DbPlaylistInfo),
}
impl DbSelectionPrintResponse {
pub fn parse(
parts: ResponseAttributes<'_>,
) -> Result<Vec<DbSelectionPrintResponse>, ResponseParserError> {
debug_assert!(!parts.is_empty());
let vec: Vec<_> = parts.into();
vec.into_iter()
.fold(Vec::new(), |mut acc, (key, value)| {
if ["directory", "file", "playlist"].contains(&key) {
acc.push((key, HashMap::new()));
}
let result = acc.last_mut().unwrap().1.insert(key, value);
debug_assert_eq!(result, None);
acc
})
.into_iter()
.map(|(key, attrs)| match key {
"directory" => DbDirectoryInfo::parse(attrs.into())
.map(DbSelectionPrintResponse::Directory),
"file" => {
DbSongInfo::parse(attrs.into()).map(DbSelectionPrintResponse::Song)
}
"playlist" => DbPlaylistInfo::parse(attrs.into())
.map(DbSelectionPrintResponse::Playlist),
p => Err(ResponseParserError::UnexpectedProperty(p)),
})
.collect::<Result<Vec<DbSelectionPrintResponse>, ResponseParserError<'_>>>()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::commands::*;
const INPUT: &str = r#"
directory: Albums
Last-Modified: 2023-05-15T17:25:12Z
directory: Albums/Name - Album
Last-Modified: 2022-12-31T17:40:04Z
file: Albums/Artist - Title.mp3
Last-Modified: 2022-12-31T02:43:04Z
Added: 2025-01-18T18:44:26Z
Format: 44100:16:2
Title: Title
Artist: Artist
Album: Album
AlbumArtist: Artist
Composer: Composer
Genre: Pop, Rock
Track: 1
Disc: 1
Date: 2022-04-27
Time: 341
duration: 341.463
playlist: Playlists/Playlist
Last-Modified: 2021-10-31T13:57:44Z
playlist: Playlists/Playlist 2
OK
"#;
#[test]
fn test_parse_db_selection_print_response() {
let parts = ResponseAttributes::new(INPUT.trim()).unwrap();
let result = DbSelectionPrintResponse::parse(parts);
assert!(result.is_ok());
}
}

View File

@@ -0,0 +1,68 @@
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use crate::commands::{expect_property_type, ResponseAttributes, ResponseParserError};
use super::{Path, PlaylistName, Seconds, Tag, TimeInterval};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct DbSongInfo {
pub file: Path,
pub range: Option<TimeInterval>,
// TODO: parse this
pub last_modified: Option<String>,
// TODO: parse this
pub added: Option<String>,
pub format: Option<String>,
pub tags: Vec<Tag>,
pub time: Option<Seconds>,
pub duration: Option<f64>,
pub playlist: Option<PlaylistName>,
}
macro_rules! remove_and_parse_next_optional_property {
($parts:ident, $name:literal, $variant:ident) => {{
let prop =
crate::commands::_expect_property_type!({ $parts.remove($name) }, $name, $variant);
crate::commands::_parse_optional_property_type!($name, prop)
}};
}
impl DbSongInfo {
pub fn parse(parts: ResponseAttributes<'_>) -> Result<Self, ResponseParserError<'_>> {
let mut parts: HashMap<_, _> = parts.into();
let file: Path = match remove_and_parse_next_optional_property!(parts, "file", Text) {
Some(f) => f,
None => return Err(ResponseParserError::MissingProperty("file")),
};
let range = remove_and_parse_next_optional_property!(parts, "Range", Text);
let last_modified = remove_and_parse_next_optional_property!(parts, "Last-Modified", Text);
let added = remove_and_parse_next_optional_property!(parts, "Added", Text);
let format = remove_and_parse_next_optional_property!(parts, "Format", Text);
let time = remove_and_parse_next_optional_property!(parts, "Time", Text);
let duration = remove_and_parse_next_optional_property!(parts, "Duration", Text);
let playlist = remove_and_parse_next_optional_property!(parts, "Playlist", Text);
let tags = parts
.into_iter()
.map(|(key, value)| {
let value = expect_property_type!(Some(value), key, Text).to_string();
Ok(Tag::new(key.to_string(), value))
})
.collect::<Result<Vec<Tag>, ResponseParserError<'_>>>()?;
Ok(DbSongInfo {
file,
range,
last_modified,
added,
format,
tags,
time,
duration,
playlist,
})
}
}

View File

@@ -239,7 +239,7 @@ impl Request {
.ok_or(RequestParserError::MissingCommandListEnd(i))?;
match line.trim() {
"command_list_begin" => {
return Err(RequestParserError::NestedCommandList(i));
return Err(RequestParserError::NestedCommandList(i))
}
"command_list_end" => {
return Ok((Request::CommandList(commands), rest));

View File

@@ -1,4 +1,4 @@
use crate::{Request, Response, common::SubSystem};
use crate::{common::SubSystem, Request, Response};
pub trait MPDServer {
type Error;