From 7a22e0f3897b059e18debdcd3a59c6f47d981738 Mon Sep 17 00:00:00 2001 From: Alexander Heldt Date: Sun, 16 Nov 2025 15:35:51 +0100 Subject: [PATCH] wip --- src/mpv/control.gleam | 55 +++++++++++++++++++++++----------- src/mpv/internal/control.gleam | 23 ++++++++++++++ src/mpv/mpv.gleam | 10 +++++-- test/mpv/control_test.gleam | 30 +++++++++++++++++++ 4 files changed, 98 insertions(+), 20 deletions(-) create mode 100644 src/mpv/internal/control.gleam create mode 100644 test/mpv/control_test.gleam diff --git a/src/mpv/control.gleam b/src/mpv/control.gleam index 0152679..9c94f26 100644 --- a/src/mpv/control.gleam +++ b/src/mpv/control.gleam @@ -1,8 +1,10 @@ import gleam/dynamic/decode +import gleam/float import gleam/json import gleam/result +import gleam/string -import mpv/internal.{type Key} +import mpv/internal.{type Key, Char} import tcp/reason.{type Reason} import tcp/tcp.{type Socket} @@ -17,7 +19,7 @@ pub type ControlError { pub fn from_key(key: Key) -> Result(Control, Nil) { case key { - internal.Char(char) -> char_control(char) + Char(char) -> char_control(char) _ -> Error(Nil) } } @@ -30,20 +32,22 @@ fn char_control(char: String) -> Result(Control, Nil) { } } -pub fn toggle_play_pause(socket: Socket) -> Result(Nil, Reason) { +pub fn toggle_play_pause(socket: Socket) -> Result(Nil, ControlError) { let command = json.object([#("command", json.array(["cycle", "pause"], of: json.string))]) - result.map(send_command(socket, command), fn(_) { Nil }) + case send_command(socket, command) { + Error(r) -> Error(ControlError(reason.to_string(r))) + Ok(_) -> Ok(Nil) + } } -// {\"data\":\"12.945425\",\"request_id\":0,\"error\":\"success\"}\n // https://mpv.io/manual/master/#command-interface-playback-time pub type PlaybackTime { - PlaybackTime(data: Int, error: String) + PlaybackTime(data: Float) } -pub fn get_playback_time(socket: Socket) -> Result(String, ControlError) { +pub fn get_playback_time(socket: Socket) -> Result(PlaybackTime, ControlError) { let command = json.object([ #( @@ -52,17 +56,34 @@ pub fn get_playback_time(socket: Socket) -> Result(String, ControlError) { ), ]) - result.map(send_command(socket, command), fn(json_string: String) { - let decoder = { - use data <- decode.field("data", decode.int) - use error <- decode.field("error", decode.string) - decode.success(PlaybackTime(data:, error:)) - } + case send_command(socket, command) { + Error(r) -> Error(ControlError(reason.to_string(r))) + Ok(json_string) -> parse_playback_time(json_string) + } +} - result.map_error(json.parse(from: json_string, using: decoder), fn(r) { - todo - }) - }) +fn parse_playback_time( + json_string: String, +) -> Result(PlaybackTime, ControlError) { + let decoder = { + let float_dececoder = fn(data_string) { + case float.parse(data_string) { + Error(_) -> decode.failure(0.0, "data") + Ok(float_value) -> decode.success(float_value) + } + } + use data <- decode.field( + "data", + decode.then(decode.string, float_dececoder), + ) + + decode.success(PlaybackTime(data)) + } + + result.map_error( + json.parse(from: string.trim(json_string), using: decoder), + fn(r) { ControlError(string.inspect(r)) }, + ) } fn send_command(socket: Socket, command: json.Json) -> Result(String, Reason) { diff --git a/src/mpv/internal/control.gleam b/src/mpv/internal/control.gleam new file mode 100644 index 0000000..d76d4d0 --- /dev/null +++ b/src/mpv/internal/control.gleam @@ -0,0 +1,23 @@ +// fn parse_playback_time( +// json_string: String, +// ) -> Result(PlaybackTime, ControlError) { +// let decoder = { +// let float_dececoder = fn(data_string) { +// case float.parse(data_string) { +// Error(_) -> decode.failure(0.0, "data") +// Ok(float_value) -> decode.success(float_value) +// } +// } +// use data <- decode.field( +// "data", +// decode.then(decode.string, float_dececoder), +// ) + +// decode.success(PlaybackTime(data)) +// } + +// result.map_error( +// json.parse(from: string.trim(json_string), using: decoder), +// fn(r) { ControlError(string.inspect(r)) }, +// ) +// } diff --git a/src/mpv/mpv.gleam b/src/mpv/mpv.gleam index 2bdeaf9..2fbe659 100644 --- a/src/mpv/mpv.gleam +++ b/src/mpv/mpv.gleam @@ -1,4 +1,5 @@ import gleam/erlang/process.{type Subject} +import gleam/float import gleam/otp/actor import gleam/result import gleam/string @@ -44,14 +45,17 @@ fn handle_message( case control { control.TogglePlayPause -> { echo "toggling play/pause" + let _ = - result.map_error(control.toggle_play_pause(state.socket), fn(r) { - echo "Could not toggle play/pause: " <> reason.to_string(r) + result.map_error(control.toggle_play_pause(state.socket), fn(err) { + echo "Could not toggle play/pause: " <> err.details }) + let _ = result.map(control.get_playback_time(state.socket), fn(playback) { - echo "playback: " <> playback + echo "playback: " <> float.to_string(playback.data) }) + actor.continue(state) } control.Exit -> { diff --git a/test/mpv/control_test.gleam b/test/mpv/control_test.gleam new file mode 100644 index 0000000..ef346a9 --- /dev/null +++ b/test/mpv/control_test.gleam @@ -0,0 +1,30 @@ +import gleam/list +import gleeunit + +import mpv/control.{type Control} +import mpv/internal.{type Key, Char} + +pub fn main() -> Nil { + gleeunit.main() +} + +type TestCase { + TestCase(key: Key, expected: Result(Control, Nil)) +} + +pub fn control_from_key_test() { + let test_cases = [ + TestCase(Char(" "), Ok(control.TogglePlayPause)), + TestCase(Char("q"), Ok(control.Exit)), + ] + + list.each(test_cases, fn(tc) { + assert tc.expected == control.from_key(tc.key) + }) +} +// pub fn parse_playback_time_test() { +// let json_string = +// "{\"data\":\"123.456789\",\"request_id\":0,\"error\":\"success\"}\n" + +// let assert Ok(_) = control.parse_p +// }