Browse and listen to thousands of radio stations across the globe right from your terminal ๐ŸŒŽ ๐Ÿ“ป ๐ŸŽตโœจ
radio rust tokio web-radio command-line-tool tui

feat(api): call a generic radio provider

+710 -397
+312 -151
Cargo.lock
··· 3 version = 4 4 5 [[package]] 6 name = "aead" 7 version = "0.3.2" 8 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 383 384 [[package]] 385 name = "axum" 386 - version = "0.6.8" 387 source = "registry+https://github.com/rust-lang/crates.io-index" 388 - checksum = "2bd379e511536bad07447f899300aa526e9bae8e6f66dc5e5ca45d7587b7c1ec" 389 dependencies = [ 390 "async-trait", 391 "axum-core", 392 - "bitflags 1.3.2", 393 "bytes", 394 "futures-util", 395 - "http", 396 - "http-body", 397 - "hyper", 398 "itoa", 399 "matchit", 400 "memchr", ··· 403 "pin-project-lite", 404 "rustversion", 405 "serde", 406 - "sync_wrapper", 407 "tower", 408 - "tower-http", 409 "tower-layer", 410 "tower-service", 411 ] 412 413 [[package]] 414 name = "axum-core" 415 - version = "0.3.2" 416 source = "registry+https://github.com/rust-lang/crates.io-index" 417 - checksum = "1cae3e661676ffbacb30f1a824089a8c9150e71017f7e1e38f2aa32009188d34" 418 dependencies = [ 419 "async-trait", 420 "bytes", 421 "futures-util", 422 - "http", 423 - "http-body", 424 "mime", 425 "rustversion", 426 "tower-layer", 427 "tower-service", 428 ] 429 430 [[package]] ··· 452 checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" 453 454 [[package]] 455 name = "bindgen" 456 version = "0.61.0" 457 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 526 527 [[package]] 528 name = "bytes" 529 - version = "1.4.0" 530 source = "registry+https://github.com/rust-lang/crates.io-index" 531 - checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" 532 533 [[package]] 534 name = "cassowary" ··· 619 "atty", 620 "bitflags 1.3.2", 621 "clap_lex", 622 - "indexmap", 623 "strsim", 624 "termcolor", 625 "textwrap", ··· 814 "bitflags 2.4.2", 815 "crossterm_winapi", 816 "libc", 817 - "mio", 818 "parking_lot", 819 "signal-hook", 820 "signal-hook-mio", ··· 955 ] 956 957 [[package]] 958 name = "errno" 959 version = "0.3.10" 960 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1147 ] 1148 1149 [[package]] 1150 name = "glob" 1151 version = "0.3.1" 1152 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1175 "futures-core", 1176 "futures-sink", 1177 "futures-util", 1178 - "http", 1179 - "indexmap", 1180 "slab", 1181 "tokio", 1182 "tokio-util", ··· 1198 "ahash", 1199 "allocator-api2", 1200 ] 1201 1202 [[package]] 1203 name = "heck" ··· 1327 ] 1328 1329 [[package]] 1330 name = "http-body" 1331 version = "0.4.5" 1332 source = "registry+https://github.com/rust-lang/crates.io-index" 1333 checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" 1334 dependencies = [ 1335 "bytes", 1336 - "http", 1337 "pin-project-lite", 1338 ] 1339 ··· 1355 "log", 1356 "rustls 0.18.1", 1357 ] 1358 - 1359 - [[package]] 1360 - name = "http-range-header" 1361 - version = "0.3.0" 1362 - source = "registry+https://github.com/rust-lang/crates.io-index" 1363 - checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" 1364 1365 [[package]] 1366 name = "http-types" ··· 1406 "futures-channel", 1407 "futures-core", 1408 "futures-util", 1409 - "h2", 1410 - "http", 1411 - "http-body", 1412 "httparse", 1413 "httpdate", 1414 "itoa", ··· 1421 ] 1422 1423 [[package]] 1424 name = "hyper-rustls" 1425 version = "0.24.2" 1426 source = "registry+https://github.com/rust-lang/crates.io-index" 1427 checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" 1428 dependencies = [ 1429 "futures-util", 1430 - "http", 1431 - "hyper", 1432 "rustls 0.21.12", 1433 "tokio", 1434 "tokio-rustls", ··· 1436 1437 [[package]] 1438 name = "hyper-timeout" 1439 - version = "0.4.1" 1440 source = "registry+https://github.com/rust-lang/crates.io-index" 1441 - checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" 1442 dependencies = [ 1443 - "hyper", 1444 "pin-project-lite", 1445 "tokio", 1446 - "tokio-io-timeout", 1447 ] 1448 1449 [[package]] ··· 1630 ] 1631 1632 [[package]] 1633 name = "indoc" 1634 version = "2.0.4" 1635 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1678 version = "2.7.1" 1679 source = "registry+https://github.com/rust-lang/crates.io-index" 1680 checksum = "30e22bd8629359895450b59ea7a776c850561b96a3b1d31321c1949d9e6c9146" 1681 - 1682 - [[package]] 1683 - name = "itertools" 1684 - version = "0.10.5" 1685 - source = "registry+https://github.com/rust-lang/crates.io-index" 1686 - checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" 1687 - dependencies = [ 1688 - "either", 1689 - ] 1690 1691 [[package]] 1692 name = "itertools" ··· 1952 ] 1953 1954 [[package]] 1955 name = "mio" 1956 version = "0.8.6" 1957 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1961 "log", 1962 "wasi 0.11.0+wasi-snapshot-preview1", 1963 "windows-sys 0.45.0", 1964 ] 1965 1966 [[package]] ··· 2139 checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" 2140 2141 [[package]] 2142 name = "oboe" 2143 version = "0.4.6" 2144 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2254 checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" 2255 dependencies = [ 2256 "fixedbitset", 2257 - "indexmap", 2258 ] 2259 2260 [[package]] ··· 2279 2280 [[package]] 2281 name = "pin-project-lite" 2282 - version = "0.2.9" 2283 source = "registry+https://github.com/rust-lang/crates.io-index" 2284 - checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" 2285 2286 [[package]] 2287 name = "pin-utils" ··· 2337 2338 [[package]] 2339 name = "prettyplease" 2340 - version = "0.1.23" 2341 source = "registry+https://github.com/rust-lang/crates.io-index" 2342 - checksum = "e97e3215779627f01ee256d2fad52f3d95e8e1c11e9fc6fd08f7cd455d5d5c78" 2343 dependencies = [ 2344 "proc-macro2", 2345 - "syn 1.0.107", 2346 ] 2347 2348 [[package]] ··· 2381 2382 [[package]] 2383 name = "prost" 2384 - version = "0.11.8" 2385 source = "registry+https://github.com/rust-lang/crates.io-index" 2386 - checksum = "e48e50df39172a3e7eb17e14642445da64996989bc212b583015435d39a58537" 2387 dependencies = [ 2388 "bytes", 2389 "prost-derive", ··· 2391 2392 [[package]] 2393 name = "prost-build" 2394 - version = "0.11.8" 2395 source = "registry+https://github.com/rust-lang/crates.io-index" 2396 - checksum = "2c828f93f5ca4826f97fedcbd3f9a536c16b12cff3dbbb4a007f932bbad95b12" 2397 dependencies = [ 2398 - "bytes", 2399 - "heck 0.4.1", 2400 - "itertools 0.10.5", 2401 - "lazy_static", 2402 "log", 2403 "multimap", 2404 "petgraph", 2405 "prettyplease", 2406 "prost", 2407 "prost-types", 2408 "regex", 2409 - "syn 1.0.107", 2410 "tempfile", 2411 - "which", 2412 ] 2413 2414 [[package]] 2415 name = "prost-derive" 2416 - version = "0.11.8" 2417 source = "registry+https://github.com/rust-lang/crates.io-index" 2418 - checksum = "4ea9b0f8cbe5e15a8a042d030bd96668db28ecb567ec37d691971ff5731d2b1b" 2419 dependencies = [ 2420 "anyhow", 2421 - "itertools 0.10.5", 2422 "proc-macro2", 2423 "quote", 2424 - "syn 1.0.107", 2425 ] 2426 2427 [[package]] 2428 name = "prost-types" 2429 - version = "0.11.8" 2430 source = "registry+https://github.com/rust-lang/crates.io-index" 2431 - checksum = "379119666929a1afd7a043aa6cf96fa67a6dce9af60c88095a4686dbce4c9c88" 2432 dependencies = [ 2433 "prost", 2434 ] ··· 2545 "compact_str", 2546 "crossterm", 2547 "indoc", 2548 - "itertools 0.12.1", 2549 "lru", 2550 "paste", 2551 "stability", ··· 2630 "encoding_rs", 2631 "futures-core", 2632 "futures-util", 2633 - "h2", 2634 - "http", 2635 - "http-body", 2636 - "hyper", 2637 "hyper-rustls", 2638 "ipnet", 2639 "js-sys", ··· 2647 "serde", 2648 "serde_json", 2649 "serde_urlencoded", 2650 - "sync_wrapper", 2651 "system-configuration", 2652 "tokio", 2653 "tokio-rustls", ··· 2717 version = "0.10.3" 2718 source = "registry+https://github.com/rust-lang/crates.io-index" 2719 checksum = "8a654c5bda722c699be6b0fe4c0d90de218928da5b724c3e467fc48865c37263" 2720 2721 [[package]] 2722 name = "rustc-hash" ··· 2988 checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" 2989 dependencies = [ 2990 "libc", 2991 - "mio", 2992 "signal-hook", 2993 ] 2994 ··· 3422 checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" 3423 3424 [[package]] 3425 name = "synstructure" 3426 version = "0.13.1" 3427 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3579 3580 [[package]] 3581 name = "tokio" 3582 - version = "1.25.0" 3583 source = "registry+https://github.com/rust-lang/crates.io-index" 3584 - checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af" 3585 dependencies = [ 3586 - "autocfg", 3587 "bytes", 3588 "libc", 3589 - "memchr", 3590 - "mio", 3591 - "num_cpus", 3592 "pin-project-lite", 3593 - "socket2 0.4.7", 3594 "tokio-macros", 3595 - "windows-sys 0.42.0", 3596 - ] 3597 - 3598 - [[package]] 3599 - name = "tokio-io-timeout" 3600 - version = "1.2.0" 3601 - source = "registry+https://github.com/rust-lang/crates.io-index" 3602 - checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" 3603 - dependencies = [ 3604 - "pin-project-lite", 3605 - "tokio", 3606 ] 3607 3608 [[package]] 3609 name = "tokio-macros" 3610 - version = "1.8.2" 3611 source = "registry+https://github.com/rust-lang/crates.io-index" 3612 - checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" 3613 dependencies = [ 3614 "proc-macro2", 3615 "quote", 3616 - "syn 1.0.107", 3617 ] 3618 3619 [[package]] ··· 3628 3629 [[package]] 3630 name = "tokio-stream" 3631 - version = "0.1.12" 3632 source = "registry+https://github.com/rust-lang/crates.io-index" 3633 - checksum = "8fb52b74f05dbf495a8fba459fdc331812b96aa086d9eb78101fa0d4569c3313" 3634 dependencies = [ 3635 "futures-core", 3636 "pin-project-lite", ··· 3663 source = "registry+https://github.com/rust-lang/crates.io-index" 3664 checksum = "56c59d8dd7d0dcbc6428bf7aa2f0e823e26e43b3c9aca15bbc9475d23e5fa12b" 3665 dependencies = [ 3666 - "indexmap", 3667 "nom8", 3668 "toml_datetime", 3669 ] 3670 3671 [[package]] 3672 name = "tonic" 3673 - version = "0.8.3" 3674 source = "registry+https://github.com/rust-lang/crates.io-index" 3675 - checksum = "8f219fad3b929bef19b1f86fbc0358d35daed8f2cac972037ac0dc10bbb8d5fb" 3676 dependencies = [ 3677 "async-stream", 3678 "async-trait", 3679 "axum", 3680 - "base64 0.13.1", 3681 "bytes", 3682 - "futures-core", 3683 - "futures-util", 3684 - "h2", 3685 - "http", 3686 - "http-body", 3687 - "hyper", 3688 "hyper-timeout", 3689 "percent-encoding 2.3.1", 3690 "pin-project", 3691 "prost", 3692 - "prost-derive", 3693 "tokio", 3694 "tokio-stream", 3695 - "tokio-util", 3696 "tower", 3697 "tower-layer", 3698 "tower-service", 3699 "tracing", 3700 - "tracing-futures", 3701 ] 3702 3703 [[package]] 3704 name = "tonic-build" 3705 - version = "0.8.4" 3706 source = "registry+https://github.com/rust-lang/crates.io-index" 3707 - checksum = "5bf5e9b9c0f7e0a7c027dcfaba7b2c60816c7049171f679d99ee2ff65d0de8c4" 3708 dependencies = [ 3709 "prettyplease", 3710 "proc-macro2", 3711 "prost-build", 3712 "quote", 3713 - "syn 1.0.107", 3714 ] 3715 3716 [[package]] 3717 name = "tonic-web" 3718 - version = "0.4.0" 3719 source = "registry+https://github.com/rust-lang/crates.io-index" 3720 - checksum = "e392f7556972523aa87ddb0fc7f2d2ce530559956706aa081bb0bd8fed158559" 3721 dependencies = [ 3722 - "base64 0.13.1", 3723 "bytes", 3724 - "futures-core", 3725 - "http", 3726 - "http-body", 3727 - "hyper", 3728 "pin-project", 3729 "tonic", 3730 "tower-service", 3731 "tracing", 3732 ] ··· 3739 dependencies = [ 3740 "futures-core", 3741 "futures-util", 3742 - "indexmap", 3743 "pin-project", 3744 "pin-project-lite", 3745 "rand 0.8.5", ··· 3753 3754 [[package]] 3755 name = "tower-http" 3756 - version = "0.3.5" 3757 source = "registry+https://github.com/rust-lang/crates.io-index" 3758 - checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" 3759 dependencies = [ 3760 - "bitflags 1.3.2", 3761 "bytes", 3762 - "futures-core", 3763 - "futures-util", 3764 - "http", 3765 - "http-body", 3766 - "http-range-header", 3767 "pin-project-lite", 3768 - "tower", 3769 "tower-layer", 3770 "tower-service", 3771 ] ··· 3789 checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" 3790 dependencies = [ 3791 "cfg-if", 3792 - "log", 3793 "pin-project-lite", 3794 "tracing-attributes", 3795 "tracing-core", ··· 3816 ] 3817 3818 [[package]] 3819 - name = "tracing-futures" 3820 - version = "0.2.5" 3821 - source = "registry+https://github.com/rust-lang/crates.io-index" 3822 - checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" 3823 - dependencies = [ 3824 - "pin-project", 3825 - "tracing", 3826 - ] 3827 - 3828 - [[package]] 3829 name = "transpose" 3830 version = "0.2.3" 3831 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3868 "derive_more", 3869 "futures", 3870 "futures-util", 3871 - "hyper", 3872 "m3u", 3873 "minimp3", 3874 "owo-colors", ··· 3888 "tokio", 3889 "tonic", 3890 "tonic-build", 3891 "tonic-web", 3892 "tunein", 3893 "url 2.5.4", ··· 4161 checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" 4162 dependencies = [ 4163 "cc", 4164 - ] 4165 - 4166 - [[package]] 4167 - name = "which" 4168 - version = "4.4.0" 4169 - source = "registry+https://github.com/rust-lang/crates.io-index" 4170 - checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" 4171 - dependencies = [ 4172 - "either", 4173 - "libc", 4174 - "once_cell", 4175 ] 4176 4177 [[package]]
··· 3 version = 4 4 5 [[package]] 6 + name = "addr2line" 7 + version = "0.24.2" 8 + source = "registry+https://github.com/rust-lang/crates.io-index" 9 + checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" 10 + dependencies = [ 11 + "gimli", 12 + ] 13 + 14 + [[package]] 15 + name = "adler2" 16 + version = "2.0.0" 17 + source = "registry+https://github.com/rust-lang/crates.io-index" 18 + checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 19 + 20 + [[package]] 21 name = "aead" 22 version = "0.3.2" 23 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 398 399 [[package]] 400 name = "axum" 401 + version = "0.7.5" 402 source = "registry+https://github.com/rust-lang/crates.io-index" 403 + checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" 404 dependencies = [ 405 "async-trait", 406 "axum-core", 407 "bytes", 408 "futures-util", 409 + "http 1.2.0", 410 + "http-body 1.0.1", 411 + "http-body-util", 412 "itoa", 413 "matchit", 414 "memchr", ··· 417 "pin-project-lite", 418 "rustversion", 419 "serde", 420 + "sync_wrapper 1.0.2", 421 "tower", 422 "tower-layer", 423 "tower-service", 424 ] 425 426 [[package]] 427 name = "axum-core" 428 + version = "0.4.5" 429 source = "registry+https://github.com/rust-lang/crates.io-index" 430 + checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" 431 dependencies = [ 432 "async-trait", 433 "bytes", 434 "futures-util", 435 + "http 1.2.0", 436 + "http-body 1.0.1", 437 + "http-body-util", 438 "mime", 439 + "pin-project-lite", 440 "rustversion", 441 + "sync_wrapper 1.0.2", 442 "tower-layer", 443 "tower-service", 444 + ] 445 + 446 + [[package]] 447 + name = "backtrace" 448 + version = "0.3.74" 449 + source = "registry+https://github.com/rust-lang/crates.io-index" 450 + checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" 451 + dependencies = [ 452 + "addr2line", 453 + "cfg-if", 454 + "libc", 455 + "miniz_oxide", 456 + "object", 457 + "rustc-demangle", 458 + "windows-targets 0.52.6", 459 ] 460 461 [[package]] ··· 483 checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" 484 485 [[package]] 486 + name = "base64" 487 + version = "0.22.1" 488 + source = "registry+https://github.com/rust-lang/crates.io-index" 489 + checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 490 + 491 + [[package]] 492 name = "bindgen" 493 version = "0.61.0" 494 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 563 564 [[package]] 565 name = "bytes" 566 + version = "1.9.0" 567 source = "registry+https://github.com/rust-lang/crates.io-index" 568 + checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" 569 570 [[package]] 571 name = "cassowary" ··· 656 "atty", 657 "bitflags 1.3.2", 658 "clap_lex", 659 + "indexmap 1.9.2", 660 "strsim", 661 "termcolor", 662 "textwrap", ··· 851 "bitflags 2.4.2", 852 "crossterm_winapi", 853 "libc", 854 + "mio 0.8.6", 855 "parking_lot", 856 "signal-hook", 857 "signal-hook-mio", ··· 992 ] 993 994 [[package]] 995 + name = "equivalent" 996 + version = "1.0.1" 997 + source = "registry+https://github.com/rust-lang/crates.io-index" 998 + checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 999 + 1000 + [[package]] 1001 name = "errno" 1002 version = "0.3.10" 1003 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1190 ] 1191 1192 [[package]] 1193 + name = "gimli" 1194 + version = "0.31.1" 1195 + source = "registry+https://github.com/rust-lang/crates.io-index" 1196 + checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 1197 + 1198 + [[package]] 1199 name = "glob" 1200 version = "0.3.1" 1201 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1224 "futures-core", 1225 "futures-sink", 1226 "futures-util", 1227 + "http 0.2.9", 1228 + "indexmap 1.9.2", 1229 + "slab", 1230 + "tokio", 1231 + "tokio-util", 1232 + "tracing", 1233 + ] 1234 + 1235 + [[package]] 1236 + name = "h2" 1237 + version = "0.4.7" 1238 + source = "registry+https://github.com/rust-lang/crates.io-index" 1239 + checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" 1240 + dependencies = [ 1241 + "atomic-waker", 1242 + "bytes", 1243 + "fnv", 1244 + "futures-core", 1245 + "futures-sink", 1246 + "http 1.2.0", 1247 + "indexmap 2.7.1", 1248 "slab", 1249 "tokio", 1250 "tokio-util", ··· 1266 "ahash", 1267 "allocator-api2", 1268 ] 1269 + 1270 + [[package]] 1271 + name = "hashbrown" 1272 + version = "0.15.2" 1273 + source = "registry+https://github.com/rust-lang/crates.io-index" 1274 + checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" 1275 1276 [[package]] 1277 name = "heck" ··· 1401 ] 1402 1403 [[package]] 1404 + name = "http" 1405 + version = "1.2.0" 1406 + source = "registry+https://github.com/rust-lang/crates.io-index" 1407 + checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" 1408 + dependencies = [ 1409 + "bytes", 1410 + "fnv", 1411 + "itoa", 1412 + ] 1413 + 1414 + [[package]] 1415 name = "http-body" 1416 version = "0.4.5" 1417 source = "registry+https://github.com/rust-lang/crates.io-index" 1418 checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" 1419 dependencies = [ 1420 "bytes", 1421 + "http 0.2.9", 1422 + "pin-project-lite", 1423 + ] 1424 + 1425 + [[package]] 1426 + name = "http-body" 1427 + version = "1.0.1" 1428 + source = "registry+https://github.com/rust-lang/crates.io-index" 1429 + checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" 1430 + dependencies = [ 1431 + "bytes", 1432 + "http 1.2.0", 1433 + ] 1434 + 1435 + [[package]] 1436 + name = "http-body-util" 1437 + version = "0.1.2" 1438 + source = "registry+https://github.com/rust-lang/crates.io-index" 1439 + checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" 1440 + dependencies = [ 1441 + "bytes", 1442 + "futures-util", 1443 + "http 1.2.0", 1444 + "http-body 1.0.1", 1445 "pin-project-lite", 1446 ] 1447 ··· 1463 "log", 1464 "rustls 0.18.1", 1465 ] 1466 1467 [[package]] 1468 name = "http-types" ··· 1508 "futures-channel", 1509 "futures-core", 1510 "futures-util", 1511 + "h2 0.3.15", 1512 + "http 0.2.9", 1513 + "http-body 0.4.5", 1514 "httparse", 1515 "httpdate", 1516 "itoa", ··· 1523 ] 1524 1525 [[package]] 1526 + name = "hyper" 1527 + version = "1.5.2" 1528 + source = "registry+https://github.com/rust-lang/crates.io-index" 1529 + checksum = "256fb8d4bd6413123cc9d91832d78325c48ff41677595be797d90f42969beae0" 1530 + dependencies = [ 1531 + "bytes", 1532 + "futures-channel", 1533 + "futures-util", 1534 + "h2 0.4.7", 1535 + "http 1.2.0", 1536 + "http-body 1.0.1", 1537 + "httparse", 1538 + "httpdate", 1539 + "itoa", 1540 + "pin-project-lite", 1541 + "smallvec", 1542 + "tokio", 1543 + "want", 1544 + ] 1545 + 1546 + [[package]] 1547 name = "hyper-rustls" 1548 version = "0.24.2" 1549 source = "registry+https://github.com/rust-lang/crates.io-index" 1550 checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" 1551 dependencies = [ 1552 "futures-util", 1553 + "http 0.2.9", 1554 + "hyper 0.14.24", 1555 "rustls 0.21.12", 1556 "tokio", 1557 "tokio-rustls", ··· 1559 1560 [[package]] 1561 name = "hyper-timeout" 1562 + version = "0.5.2" 1563 source = "registry+https://github.com/rust-lang/crates.io-index" 1564 + checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" 1565 dependencies = [ 1566 + "hyper 1.5.2", 1567 + "hyper-util", 1568 "pin-project-lite", 1569 "tokio", 1570 + "tower-service", 1571 + ] 1572 + 1573 + [[package]] 1574 + name = "hyper-util" 1575 + version = "0.1.10" 1576 + source = "registry+https://github.com/rust-lang/crates.io-index" 1577 + checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" 1578 + dependencies = [ 1579 + "bytes", 1580 + "futures-channel", 1581 + "futures-util", 1582 + "http 1.2.0", 1583 + "http-body 1.0.1", 1584 + "hyper 1.5.2", 1585 + "pin-project-lite", 1586 + "socket2 0.5.8", 1587 + "tokio", 1588 + "tower-service", 1589 + "tracing", 1590 ] 1591 1592 [[package]] ··· 1773 ] 1774 1775 [[package]] 1776 + name = "indexmap" 1777 + version = "2.7.1" 1778 + source = "registry+https://github.com/rust-lang/crates.io-index" 1779 + checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" 1780 + dependencies = [ 1781 + "equivalent", 1782 + "hashbrown 0.15.2", 1783 + ] 1784 + 1785 + [[package]] 1786 name = "indoc" 1787 version = "2.0.4" 1788 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1831 version = "2.7.1" 1832 source = "registry+https://github.com/rust-lang/crates.io-index" 1833 checksum = "30e22bd8629359895450b59ea7a776c850561b96a3b1d31321c1949d9e6c9146" 1834 1835 [[package]] 1836 name = "itertools" ··· 2096 ] 2097 2098 [[package]] 2099 + name = "miniz_oxide" 2100 + version = "0.8.3" 2101 + source = "registry+https://github.com/rust-lang/crates.io-index" 2102 + checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924" 2103 + dependencies = [ 2104 + "adler2", 2105 + ] 2106 + 2107 + [[package]] 2108 name = "mio" 2109 version = "0.8.6" 2110 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2114 "log", 2115 "wasi 0.11.0+wasi-snapshot-preview1", 2116 "windows-sys 0.45.0", 2117 + ] 2118 + 2119 + [[package]] 2120 + name = "mio" 2121 + version = "1.0.3" 2122 + source = "registry+https://github.com/rust-lang/crates.io-index" 2123 + checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" 2124 + dependencies = [ 2125 + "libc", 2126 + "wasi 0.11.0+wasi-snapshot-preview1", 2127 + "windows-sys 0.52.0", 2128 ] 2129 2130 [[package]] ··· 2303 checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" 2304 2305 [[package]] 2306 + name = "object" 2307 + version = "0.36.7" 2308 + source = "registry+https://github.com/rust-lang/crates.io-index" 2309 + checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" 2310 + dependencies = [ 2311 + "memchr", 2312 + ] 2313 + 2314 + [[package]] 2315 name = "oboe" 2316 version = "0.4.6" 2317 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2427 checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" 2428 dependencies = [ 2429 "fixedbitset", 2430 + "indexmap 1.9.2", 2431 ] 2432 2433 [[package]] ··· 2452 2453 [[package]] 2454 name = "pin-project-lite" 2455 + version = "0.2.16" 2456 source = "registry+https://github.com/rust-lang/crates.io-index" 2457 + checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 2458 2459 [[package]] 2460 name = "pin-utils" ··· 2510 2511 [[package]] 2512 name = "prettyplease" 2513 + version = "0.2.17" 2514 source = "registry+https://github.com/rust-lang/crates.io-index" 2515 + checksum = "8d3928fb5db768cb86f891ff014f0144589297e3c6a1aba6ed7cecfdace270c7" 2516 dependencies = [ 2517 "proc-macro2", 2518 + "syn 2.0.51", 2519 ] 2520 2521 [[package]] ··· 2554 2555 [[package]] 2556 name = "prost" 2557 + version = "0.13.4" 2558 source = "registry+https://github.com/rust-lang/crates.io-index" 2559 + checksum = "2c0fef6c4230e4ccf618a35c59d7ede15dea37de8427500f50aff708806e42ec" 2560 dependencies = [ 2561 "bytes", 2562 "prost-derive", ··· 2564 2565 [[package]] 2566 name = "prost-build" 2567 + version = "0.13.4" 2568 source = "registry+https://github.com/rust-lang/crates.io-index" 2569 + checksum = "d0f3e5beed80eb580c68e2c600937ac2c4eedabdfd5ef1e5b7ea4f3fba84497b" 2570 dependencies = [ 2571 + "heck 0.5.0", 2572 + "itertools", 2573 "log", 2574 "multimap", 2575 + "once_cell", 2576 "petgraph", 2577 "prettyplease", 2578 "prost", 2579 "prost-types", 2580 "regex", 2581 + "syn 2.0.51", 2582 "tempfile", 2583 ] 2584 2585 [[package]] 2586 name = "prost-derive" 2587 + version = "0.13.4" 2588 source = "registry+https://github.com/rust-lang/crates.io-index" 2589 + checksum = "157c5a9d7ea5c2ed2d9fb8f495b64759f7816c7eaea54ba3978f0d63000162e3" 2590 dependencies = [ 2591 "anyhow", 2592 + "itertools", 2593 "proc-macro2", 2594 "quote", 2595 + "syn 2.0.51", 2596 ] 2597 2598 [[package]] 2599 name = "prost-types" 2600 + version = "0.13.4" 2601 source = "registry+https://github.com/rust-lang/crates.io-index" 2602 + checksum = "cc2f1e56baa61e93533aebc21af4d2134b70f66275e0fcdf3cbe43d77ff7e8fc" 2603 dependencies = [ 2604 "prost", 2605 ] ··· 2716 "compact_str", 2717 "crossterm", 2718 "indoc", 2719 + "itertools", 2720 "lru", 2721 "paste", 2722 "stability", ··· 2801 "encoding_rs", 2802 "futures-core", 2803 "futures-util", 2804 + "h2 0.3.15", 2805 + "http 0.2.9", 2806 + "http-body 0.4.5", 2807 + "hyper 0.14.24", 2808 "hyper-rustls", 2809 "ipnet", 2810 "js-sys", ··· 2818 "serde", 2819 "serde_json", 2820 "serde_urlencoded", 2821 + "sync_wrapper 0.1.2", 2822 "system-configuration", 2823 "tokio", 2824 "tokio-rustls", ··· 2888 version = "0.10.3" 2889 source = "registry+https://github.com/rust-lang/crates.io-index" 2890 checksum = "8a654c5bda722c699be6b0fe4c0d90de218928da5b724c3e467fc48865c37263" 2891 + 2892 + [[package]] 2893 + name = "rustc-demangle" 2894 + version = "0.1.24" 2895 + source = "registry+https://github.com/rust-lang/crates.io-index" 2896 + checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 2897 2898 [[package]] 2899 name = "rustc-hash" ··· 3165 checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" 3166 dependencies = [ 3167 "libc", 3168 + "mio 0.8.6", 3169 "signal-hook", 3170 ] 3171 ··· 3599 checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" 3600 3601 [[package]] 3602 + name = "sync_wrapper" 3603 + version = "1.0.2" 3604 + source = "registry+https://github.com/rust-lang/crates.io-index" 3605 + checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" 3606 + 3607 + [[package]] 3608 name = "synstructure" 3609 version = "0.13.1" 3610 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3762 3763 [[package]] 3764 name = "tokio" 3765 + version = "1.43.0" 3766 source = "registry+https://github.com/rust-lang/crates.io-index" 3767 + checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" 3768 dependencies = [ 3769 + "backtrace", 3770 "bytes", 3771 "libc", 3772 + "mio 1.0.3", 3773 "pin-project-lite", 3774 + "socket2 0.5.8", 3775 "tokio-macros", 3776 + "windows-sys 0.52.0", 3777 ] 3778 3779 [[package]] 3780 name = "tokio-macros" 3781 + version = "2.5.0" 3782 source = "registry+https://github.com/rust-lang/crates.io-index" 3783 + checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" 3784 dependencies = [ 3785 "proc-macro2", 3786 "quote", 3787 + "syn 2.0.51", 3788 ] 3789 3790 [[package]] ··· 3799 3800 [[package]] 3801 name = "tokio-stream" 3802 + version = "0.1.17" 3803 source = "registry+https://github.com/rust-lang/crates.io-index" 3804 + checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" 3805 dependencies = [ 3806 "futures-core", 3807 "pin-project-lite", ··· 3834 source = "registry+https://github.com/rust-lang/crates.io-index" 3835 checksum = "56c59d8dd7d0dcbc6428bf7aa2f0e823e26e43b3c9aca15bbc9475d23e5fa12b" 3836 dependencies = [ 3837 + "indexmap 1.9.2", 3838 "nom8", 3839 "toml_datetime", 3840 ] 3841 3842 [[package]] 3843 name = "tonic" 3844 + version = "0.12.3" 3845 source = "registry+https://github.com/rust-lang/crates.io-index" 3846 + checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" 3847 dependencies = [ 3848 "async-stream", 3849 "async-trait", 3850 "axum", 3851 + "base64 0.22.1", 3852 "bytes", 3853 + "h2 0.4.7", 3854 + "http 1.2.0", 3855 + "http-body 1.0.1", 3856 + "http-body-util", 3857 + "hyper 1.5.2", 3858 "hyper-timeout", 3859 + "hyper-util", 3860 "percent-encoding 2.3.1", 3861 "pin-project", 3862 "prost", 3863 + "socket2 0.5.8", 3864 "tokio", 3865 "tokio-stream", 3866 "tower", 3867 "tower-layer", 3868 "tower-service", 3869 "tracing", 3870 ] 3871 3872 [[package]] 3873 name = "tonic-build" 3874 + version = "0.12.3" 3875 source = "registry+https://github.com/rust-lang/crates.io-index" 3876 + checksum = "9557ce109ea773b399c9b9e5dca39294110b74f1f342cb347a80d1fce8c26a11" 3877 dependencies = [ 3878 "prettyplease", 3879 "proc-macro2", 3880 "prost-build", 3881 + "prost-types", 3882 "quote", 3883 + "syn 2.0.51", 3884 + ] 3885 + 3886 + [[package]] 3887 + name = "tonic-reflection" 3888 + version = "0.12.3" 3889 + source = "registry+https://github.com/rust-lang/crates.io-index" 3890 + checksum = "878d81f52e7fcfd80026b7fdb6a9b578b3c3653ba987f87f0dce4b64043cba27" 3891 + dependencies = [ 3892 + "prost", 3893 + "prost-types", 3894 + "tokio", 3895 + "tokio-stream", 3896 + "tonic", 3897 ] 3898 3899 [[package]] 3900 name = "tonic-web" 3901 + version = "0.12.3" 3902 source = "registry+https://github.com/rust-lang/crates.io-index" 3903 + checksum = "5299dd20801ad736dccb4a5ea0da7376e59cd98f213bf1c3d478cf53f4834b58" 3904 dependencies = [ 3905 + "base64 0.22.1", 3906 "bytes", 3907 + "http 1.2.0", 3908 + "http-body 1.0.1", 3909 + "http-body-util", 3910 "pin-project", 3911 + "tokio-stream", 3912 "tonic", 3913 + "tower-http", 3914 + "tower-layer", 3915 "tower-service", 3916 "tracing", 3917 ] ··· 3924 dependencies = [ 3925 "futures-core", 3926 "futures-util", 3927 + "indexmap 1.9.2", 3928 "pin-project", 3929 "pin-project-lite", 3930 "rand 0.8.5", ··· 3938 3939 [[package]] 3940 name = "tower-http" 3941 + version = "0.5.2" 3942 source = "registry+https://github.com/rust-lang/crates.io-index" 3943 + checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" 3944 dependencies = [ 3945 + "bitflags 2.4.2", 3946 "bytes", 3947 + "http 1.2.0", 3948 + "http-body 1.0.1", 3949 + "http-body-util", 3950 "pin-project-lite", 3951 "tower-layer", 3952 "tower-service", 3953 ] ··· 3971 checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" 3972 dependencies = [ 3973 "cfg-if", 3974 "pin-project-lite", 3975 "tracing-attributes", 3976 "tracing-core", ··· 3997 ] 3998 3999 [[package]] 4000 name = "transpose" 4001 version = "0.2.3" 4002 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 4039 "derive_more", 4040 "futures", 4041 "futures-util", 4042 + "hyper 0.14.24", 4043 "m3u", 4044 "minimp3", 4045 "owo-colors", ··· 4059 "tokio", 4060 "tonic", 4061 "tonic-build", 4062 + "tonic-reflection", 4063 "tonic-web", 4064 "tunein", 4065 "url 2.5.4", ··· 4333 checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" 4334 dependencies = [ 4335 "cc", 4336 ] 4337 4338 [[package]]
+6 -5
Cargo.toml
··· 36 minimp3 = "0.5.1" 37 owo-colors = "3.5.0" 38 pls = "0.2.2" 39 - prost = "0.11.8" 40 radiobrowser = { version = "0.6.1", features = ["default-rustls"], default-features = false } 41 ratatui = "0.26.1" 42 regex = "1.11.1" ··· 48 symphonia = {version = "0.5.1", features = ["aac", "alac", "mp3", "isomp4", "flac"]} 49 termion = "2.0.1" 50 thiserror = "1.0.58" 51 - tokio = {version = "1.24.2", features = ["tokio-macros", "macros", "rt", "rt-multi-thread"]} 52 - tonic = "0.8.3" 53 - tonic-web = "0.4.0" 54 tunein = "0.1.3" 55 url = "2.3.1" 56 57 [build-dependencies] 58 - tonic-build = "0.8"
··· 36 minimp3 = "0.5.1" 37 owo-colors = "3.5.0" 38 pls = "0.2.2" 39 + prost = "0.13.2" 40 radiobrowser = { version = "0.6.1", features = ["default-rustls"], default-features = false } 41 ratatui = "0.26.1" 42 regex = "1.11.1" ··· 48 symphonia = {version = "0.5.1", features = ["aac", "alac", "mp3", "isomp4", "flac"]} 49 termion = "2.0.1" 50 thiserror = "1.0.58" 51 + tokio = {version = "1.36.0", features = ["tokio-macros", "macros", "rt", "rt-multi-thread"]} 52 + tonic = "0.12.3" 53 + tonic-reflection = "0.12.3" 54 + tonic-web = "0.12.3" 55 tunein = "0.1.3" 56 url = "2.3.1" 57 58 [build-dependencies] 59 + tonic-build = "0.12.3"
+12 -9
build.rs
··· 1 fn main() -> Result<(), Box<dyn std::error::Error>> { 2 - tonic_build::configure().out_dir("src/api").compile( 3 - &[ 4 - "proto/objects/v1alpha1/category.proto", 5 - "proto/objects/v1alpha1/station.proto", 6 - "proto/tunein/v1alpha1/browse.proto", 7 - "proto/tunein/v1alpha1/playback.proto", 8 - ], 9 - &["proto"], 10 - )?; 11 Ok(()) 12 }
··· 1 fn main() -> Result<(), Box<dyn std::error::Error>> { 2 + tonic_build::configure() 3 + .out_dir("src/api") 4 + .file_descriptor_set_path("src/api/descriptor.bin") 5 + .compile_protos( 6 + &[ 7 + "proto/objects/v1alpha1/category.proto", 8 + "proto/objects/v1alpha1/station.proto", 9 + "proto/tunein/v1alpha1/browse.proto", 10 + "proto/tunein/v1alpha1/playback.proto", 11 + ], 12 + &["proto"], 13 + )?; 14 Ok(()) 15 }
src/api/descriptor.bin

This is a binary file and will not be displayed.

+1 -3
src/api/objects.v1alpha1.rs
··· 1 - #[allow(clippy::derive_partial_eq_without_eq)] 2 #[derive(Clone, PartialEq, ::prost::Message)] 3 pub struct Station { 4 #[prost(string, tag = "1")] ··· 8 #[prost(string, tag = "3")] 9 pub playing: ::prost::alloc::string::String, 10 } 11 - #[allow(clippy::derive_partial_eq_without_eq)] 12 #[derive(Clone, PartialEq, ::prost::Message)] 13 pub struct StationLinkDetails { 14 #[prost(uint32, tag = "1")] ··· 38 #[prost(string, tag = "13")] 39 pub url: ::prost::alloc::string::String, 40 } 41 - #[allow(clippy::derive_partial_eq_without_eq)] 42 #[derive(Clone, PartialEq, ::prost::Message)] 43 pub struct Category { 44 #[prost(string, tag = "1")]
··· 1 + // This file is @generated by prost-build. 2 #[derive(Clone, PartialEq, ::prost::Message)] 3 pub struct Station { 4 #[prost(string, tag = "1")] ··· 8 #[prost(string, tag = "3")] 9 pub playing: ::prost::alloc::string::String, 10 } 11 #[derive(Clone, PartialEq, ::prost::Message)] 12 pub struct StationLinkDetails { 13 #[prost(uint32, tag = "1")] ··· 37 #[prost(string, tag = "13")] 38 pub url: ::prost::alloc::string::String, 39 } 40 #[derive(Clone, PartialEq, ::prost::Message)] 41 pub struct Category { 42 #[prost(string, tag = "1")]
+296 -140
src/api/tunein.v1alpha1.rs
··· 1 - #[allow(clippy::derive_partial_eq_without_eq)] 2 - #[derive(Clone, PartialEq, ::prost::Message)] 3 pub struct GetCategoriesRequest {} 4 - #[allow(clippy::derive_partial_eq_without_eq)] 5 #[derive(Clone, PartialEq, ::prost::Message)] 6 pub struct GetCategoriesResponse { 7 #[prost(message, repeated, tag = "1")] 8 pub categories: ::prost::alloc::vec::Vec<super::super::objects::v1alpha1::Category>, 9 } 10 - #[allow(clippy::derive_partial_eq_without_eq)] 11 #[derive(Clone, PartialEq, ::prost::Message)] 12 pub struct BrowseCategoryRequest { 13 #[prost(string, tag = "1")] 14 pub category_id: ::prost::alloc::string::String, 15 } 16 - #[allow(clippy::derive_partial_eq_without_eq)] 17 #[derive(Clone, PartialEq, ::prost::Message)] 18 pub struct BrowseCategoryResponse { 19 #[prost(message, repeated, tag = "1")] 20 pub categories: ::prost::alloc::vec::Vec<super::super::objects::v1alpha1::Category>, 21 } 22 - #[allow(clippy::derive_partial_eq_without_eq)] 23 #[derive(Clone, PartialEq, ::prost::Message)] 24 pub struct GetStationDetailsRequest { 25 #[prost(string, tag = "1")] 26 pub id: ::prost::alloc::string::String, 27 } 28 - #[allow(clippy::derive_partial_eq_without_eq)] 29 #[derive(Clone, PartialEq, ::prost::Message)] 30 pub struct GetStationDetailsResponse { 31 #[prost(message, repeated, tag = "1")] ··· 35 } 36 /// Generated client implementations. 37 pub mod browse_service_client { 38 - #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] 39 use tonic::codegen::*; 40 use tonic::codegen::http::Uri; 41 #[derive(Debug, Clone)] ··· 46 /// Attempt to create a new client by connecting to a given endpoint. 47 pub async fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error> 48 where 49 - D: std::convert::TryInto<tonic::transport::Endpoint>, 50 D::Error: Into<StdError>, 51 { 52 let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; ··· 57 where 58 T: tonic::client::GrpcService<tonic::body::BoxBody>, 59 T::Error: Into<StdError>, 60 - T::ResponseBody: Body<Data = Bytes> + Send + 'static, 61 - <T::ResponseBody as Body>::Error: Into<StdError> + Send, 62 { 63 pub fn new(inner: T) -> Self { 64 let inner = tonic::client::Grpc::new(inner); ··· 83 >, 84 <T as tonic::codegen::Service< 85 http::Request<tonic::body::BoxBody>, 86 - >>::Error: Into<StdError> + Send + Sync, 87 { 88 BrowseServiceClient::new(InterceptedService::new(inner, interceptor)) 89 } ··· 102 self.inner = self.inner.accept_compressed(encoding); 103 self 104 } 105 pub async fn get_categories( 106 &mut self, 107 request: impl tonic::IntoRequest<super::GetCategoriesRequest>, 108 - ) -> Result<tonic::Response<super::GetCategoriesResponse>, tonic::Status> { 109 self.inner 110 .ready() 111 .await 112 .map_err(|e| { 113 - tonic::Status::new( 114 - tonic::Code::Unknown, 115 format!("Service was not ready: {}", e.into()), 116 ) 117 })?; ··· 119 let path = http::uri::PathAndQuery::from_static( 120 "/tunein.v1alpha1.BrowseService/GetCategories", 121 ); 122 - self.inner.unary(request.into_request(), path, codec).await 123 } 124 pub async fn browse_category( 125 &mut self, 126 request: impl tonic::IntoRequest<super::BrowseCategoryRequest>, 127 - ) -> Result<tonic::Response<super::BrowseCategoryResponse>, tonic::Status> { 128 self.inner 129 .ready() 130 .await 131 .map_err(|e| { 132 - tonic::Status::new( 133 - tonic::Code::Unknown, 134 format!("Service was not ready: {}", e.into()), 135 ) 136 })?; ··· 138 let path = http::uri::PathAndQuery::from_static( 139 "/tunein.v1alpha1.BrowseService/BrowseCategory", 140 ); 141 - self.inner.unary(request.into_request(), path, codec).await 142 } 143 pub async fn get_station_details( 144 &mut self, 145 request: impl tonic::IntoRequest<super::GetStationDetailsRequest>, 146 - ) -> Result<tonic::Response<super::GetStationDetailsResponse>, tonic::Status> { 147 self.inner 148 .ready() 149 .await 150 .map_err(|e| { 151 - tonic::Status::new( 152 - tonic::Code::Unknown, 153 format!("Service was not ready: {}", e.into()), 154 ) 155 })?; ··· 157 let path = http::uri::PathAndQuery::from_static( 158 "/tunein.v1alpha1.BrowseService/GetStationDetails", 159 ); 160 - self.inner.unary(request.into_request(), path, codec).await 161 } 162 } 163 } 164 /// Generated server implementations. 165 pub mod browse_service_server { 166 - #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] 167 use tonic::codegen::*; 168 /// Generated trait containing gRPC methods that should be implemented for use with BrowseServiceServer. 169 #[async_trait] 170 - pub trait BrowseService: Send + Sync + 'static { 171 async fn get_categories( 172 &self, 173 request: tonic::Request<super::GetCategoriesRequest>, 174 - ) -> Result<tonic::Response<super::GetCategoriesResponse>, tonic::Status>; 175 async fn browse_category( 176 &self, 177 request: tonic::Request<super::BrowseCategoryRequest>, 178 - ) -> Result<tonic::Response<super::BrowseCategoryResponse>, tonic::Status>; 179 async fn get_station_details( 180 &self, 181 request: tonic::Request<super::GetStationDetailsRequest>, 182 - ) -> Result<tonic::Response<super::GetStationDetailsResponse>, tonic::Status>; 183 } 184 #[derive(Debug)] 185 - pub struct BrowseServiceServer<T: BrowseService> { 186 - inner: _Inner<T>, 187 accept_compression_encodings: EnabledCompressionEncodings, 188 send_compression_encodings: EnabledCompressionEncodings, 189 } 190 - struct _Inner<T>(Arc<T>); 191 - impl<T: BrowseService> BrowseServiceServer<T> { 192 pub fn new(inner: T) -> Self { 193 Self::from_arc(Arc::new(inner)) 194 } 195 pub fn from_arc(inner: Arc<T>) -> Self { 196 - let inner = _Inner(inner); 197 Self { 198 inner, 199 accept_compression_encodings: Default::default(), 200 send_compression_encodings: Default::default(), 201 } 202 } 203 pub fn with_interceptor<F>( ··· 221 self.send_compression_encodings.enable(encoding); 222 self 223 } 224 } 225 impl<T, B> tonic::codegen::Service<http::Request<B>> for BrowseServiceServer<T> 226 where 227 T: BrowseService, 228 - B: Body + Send + 'static, 229 - B::Error: Into<StdError> + Send + 'static, 230 { 231 type Response = http::Response<tonic::body::BoxBody>; 232 type Error = std::convert::Infallible; ··· 234 fn poll_ready( 235 &mut self, 236 _cx: &mut Context<'_>, 237 - ) -> Poll<Result<(), Self::Error>> { 238 Poll::Ready(Ok(())) 239 } 240 fn call(&mut self, req: http::Request<B>) -> Self::Future { 241 - let inner = self.inner.clone(); 242 match req.uri().path() { 243 "/tunein.v1alpha1.BrowseService/GetCategories" => { 244 #[allow(non_camel_case_types)] ··· 256 &mut self, 257 request: tonic::Request<super::GetCategoriesRequest>, 258 ) -> Self::Future { 259 - let inner = self.0.clone(); 260 let fut = async move { 261 - (*inner).get_categories(request).await 262 }; 263 Box::pin(fut) 264 } 265 } 266 let accept_compression_encodings = self.accept_compression_encodings; 267 let send_compression_encodings = self.send_compression_encodings; 268 let inner = self.inner.clone(); 269 let fut = async move { 270 - let inner = inner.0; 271 let method = GetCategoriesSvc(inner); 272 let codec = tonic::codec::ProstCodec::default(); 273 let mut grpc = tonic::server::Grpc::new(codec) 274 .apply_compression_config( 275 accept_compression_encodings, 276 send_compression_encodings, 277 ); 278 let res = grpc.unary(method, req).await; 279 Ok(res) ··· 296 &mut self, 297 request: tonic::Request<super::BrowseCategoryRequest>, 298 ) -> Self::Future { 299 - let inner = self.0.clone(); 300 let fut = async move { 301 - (*inner).browse_category(request).await 302 }; 303 Box::pin(fut) 304 } 305 } 306 let accept_compression_encodings = self.accept_compression_encodings; 307 let send_compression_encodings = self.send_compression_encodings; 308 let inner = self.inner.clone(); 309 let fut = async move { 310 - let inner = inner.0; 311 let method = BrowseCategorySvc(inner); 312 let codec = tonic::codec::ProstCodec::default(); 313 let mut grpc = tonic::server::Grpc::new(codec) 314 .apply_compression_config( 315 accept_compression_encodings, 316 send_compression_encodings, 317 ); 318 let res = grpc.unary(method, req).await; 319 Ok(res) ··· 336 &mut self, 337 request: tonic::Request<super::GetStationDetailsRequest>, 338 ) -> Self::Future { 339 - let inner = self.0.clone(); 340 let fut = async move { 341 - (*inner).get_station_details(request).await 342 }; 343 Box::pin(fut) 344 } 345 } 346 let accept_compression_encodings = self.accept_compression_encodings; 347 let send_compression_encodings = self.send_compression_encodings; 348 let inner = self.inner.clone(); 349 let fut = async move { 350 - let inner = inner.0; 351 let method = GetStationDetailsSvc(inner); 352 let codec = tonic::codec::ProstCodec::default(); 353 let mut grpc = tonic::server::Grpc::new(codec) 354 .apply_compression_config( 355 accept_compression_encodings, 356 send_compression_encodings, 357 ); 358 let res = grpc.unary(method, req).await; 359 Ok(res) ··· 362 } 363 _ => { 364 Box::pin(async move { 365 - Ok( 366 - http::Response::builder() 367 - .status(200) 368 - .header("grpc-status", "12") 369 - .header("content-type", "application/grpc") 370 - .body(empty_body()) 371 - .unwrap(), 372 - ) 373 }) 374 } 375 } 376 } 377 } 378 - impl<T: BrowseService> Clone for BrowseServiceServer<T> { 379 fn clone(&self) -> Self { 380 let inner = self.inner.clone(); 381 Self { 382 inner, 383 accept_compression_encodings: self.accept_compression_encodings, 384 send_compression_encodings: self.send_compression_encodings, 385 } 386 } 387 } 388 - impl<T: BrowseService> Clone for _Inner<T> { 389 - fn clone(&self) -> Self { 390 - Self(self.0.clone()) 391 - } 392 - } 393 - impl<T: std::fmt::Debug> std::fmt::Debug for _Inner<T> { 394 - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 395 - write!(f, "{:?}", self.0) 396 - } 397 - } 398 - impl<T: BrowseService> tonic::server::NamedService for BrowseServiceServer<T> { 399 - const NAME: &'static str = "tunein.v1alpha1.BrowseService"; 400 } 401 } 402 - #[allow(clippy::derive_partial_eq_without_eq)] 403 - #[derive(Clone, PartialEq, ::prost::Message)] 404 pub struct PlayOrPauseRequest {} 405 - #[allow(clippy::derive_partial_eq_without_eq)] 406 - #[derive(Clone, PartialEq, ::prost::Message)] 407 pub struct PlayOrPauseResponse {} 408 - #[allow(clippy::derive_partial_eq_without_eq)] 409 - #[derive(Clone, PartialEq, ::prost::Message)] 410 pub struct StopRequest {} 411 - #[allow(clippy::derive_partial_eq_without_eq)] 412 - #[derive(Clone, PartialEq, ::prost::Message)] 413 pub struct StopResponse {} 414 - #[allow(clippy::derive_partial_eq_without_eq)] 415 #[derive(Clone, PartialEq, ::prost::Message)] 416 pub struct PlayRequest { 417 #[prost(string, tag = "1")] 418 pub station_name_or_id: ::prost::alloc::string::String, 419 } 420 - #[allow(clippy::derive_partial_eq_without_eq)] 421 - #[derive(Clone, PartialEq, ::prost::Message)] 422 pub struct PlayResponse {} 423 /// Generated client implementations. 424 pub mod playback_service_client { 425 - #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] 426 use tonic::codegen::*; 427 use tonic::codegen::http::Uri; 428 #[derive(Debug, Clone)] ··· 433 /// Attempt to create a new client by connecting to a given endpoint. 434 pub async fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error> 435 where 436 - D: std::convert::TryInto<tonic::transport::Endpoint>, 437 D::Error: Into<StdError>, 438 { 439 let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; ··· 444 where 445 T: tonic::client::GrpcService<tonic::body::BoxBody>, 446 T::Error: Into<StdError>, 447 - T::ResponseBody: Body<Data = Bytes> + Send + 'static, 448 - <T::ResponseBody as Body>::Error: Into<StdError> + Send, 449 { 450 pub fn new(inner: T) -> Self { 451 let inner = tonic::client::Grpc::new(inner); ··· 470 >, 471 <T as tonic::codegen::Service< 472 http::Request<tonic::body::BoxBody>, 473 - >>::Error: Into<StdError> + Send + Sync, 474 { 475 PlaybackServiceClient::new(InterceptedService::new(inner, interceptor)) 476 } ··· 489 self.inner = self.inner.accept_compressed(encoding); 490 self 491 } 492 pub async fn play( 493 &mut self, 494 request: impl tonic::IntoRequest<super::PlayRequest>, 495 - ) -> Result<tonic::Response<super::PlayResponse>, tonic::Status> { 496 self.inner 497 .ready() 498 .await 499 .map_err(|e| { 500 - tonic::Status::new( 501 - tonic::Code::Unknown, 502 format!("Service was not ready: {}", e.into()), 503 ) 504 })?; ··· 506 let path = http::uri::PathAndQuery::from_static( 507 "/tunein.v1alpha1.PlaybackService/Play", 508 ); 509 - self.inner.unary(request.into_request(), path, codec).await 510 } 511 pub async fn stop( 512 &mut self, 513 request: impl tonic::IntoRequest<super::StopRequest>, 514 - ) -> Result<tonic::Response<super::StopResponse>, tonic::Status> { 515 self.inner 516 .ready() 517 .await 518 .map_err(|e| { 519 - tonic::Status::new( 520 - tonic::Code::Unknown, 521 format!("Service was not ready: {}", e.into()), 522 ) 523 })?; ··· 525 let path = http::uri::PathAndQuery::from_static( 526 "/tunein.v1alpha1.PlaybackService/Stop", 527 ); 528 - self.inner.unary(request.into_request(), path, codec).await 529 } 530 pub async fn play_or_pause( 531 &mut self, 532 request: impl tonic::IntoRequest<super::PlayOrPauseRequest>, 533 - ) -> Result<tonic::Response<super::PlayOrPauseResponse>, tonic::Status> { 534 self.inner 535 .ready() 536 .await 537 .map_err(|e| { 538 - tonic::Status::new( 539 - tonic::Code::Unknown, 540 format!("Service was not ready: {}", e.into()), 541 ) 542 })?; ··· 544 let path = http::uri::PathAndQuery::from_static( 545 "/tunein.v1alpha1.PlaybackService/PlayOrPause", 546 ); 547 - self.inner.unary(request.into_request(), path, codec).await 548 } 549 } 550 } 551 /// Generated server implementations. 552 pub mod playback_service_server { 553 - #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] 554 use tonic::codegen::*; 555 /// Generated trait containing gRPC methods that should be implemented for use with PlaybackServiceServer. 556 #[async_trait] 557 - pub trait PlaybackService: Send + Sync + 'static { 558 async fn play( 559 &self, 560 request: tonic::Request<super::PlayRequest>, 561 - ) -> Result<tonic::Response<super::PlayResponse>, tonic::Status>; 562 async fn stop( 563 &self, 564 request: tonic::Request<super::StopRequest>, 565 - ) -> Result<tonic::Response<super::StopResponse>, tonic::Status>; 566 async fn play_or_pause( 567 &self, 568 request: tonic::Request<super::PlayOrPauseRequest>, 569 - ) -> Result<tonic::Response<super::PlayOrPauseResponse>, tonic::Status>; 570 } 571 #[derive(Debug)] 572 - pub struct PlaybackServiceServer<T: PlaybackService> { 573 - inner: _Inner<T>, 574 accept_compression_encodings: EnabledCompressionEncodings, 575 send_compression_encodings: EnabledCompressionEncodings, 576 } 577 - struct _Inner<T>(Arc<T>); 578 - impl<T: PlaybackService> PlaybackServiceServer<T> { 579 pub fn new(inner: T) -> Self { 580 Self::from_arc(Arc::new(inner)) 581 } 582 pub fn from_arc(inner: Arc<T>) -> Self { 583 - let inner = _Inner(inner); 584 Self { 585 inner, 586 accept_compression_encodings: Default::default(), 587 send_compression_encodings: Default::default(), 588 } 589 } 590 pub fn with_interceptor<F>( ··· 608 self.send_compression_encodings.enable(encoding); 609 self 610 } 611 } 612 impl<T, B> tonic::codegen::Service<http::Request<B>> for PlaybackServiceServer<T> 613 where 614 T: PlaybackService, 615 - B: Body + Send + 'static, 616 - B::Error: Into<StdError> + Send + 'static, 617 { 618 type Response = http::Response<tonic::body::BoxBody>; 619 type Error = std::convert::Infallible; ··· 621 fn poll_ready( 622 &mut self, 623 _cx: &mut Context<'_>, 624 - ) -> Poll<Result<(), Self::Error>> { 625 Poll::Ready(Ok(())) 626 } 627 fn call(&mut self, req: http::Request<B>) -> Self::Future { 628 - let inner = self.inner.clone(); 629 match req.uri().path() { 630 "/tunein.v1alpha1.PlaybackService/Play" => { 631 #[allow(non_camel_case_types)] ··· 642 &mut self, 643 request: tonic::Request<super::PlayRequest>, 644 ) -> Self::Future { 645 - let inner = self.0.clone(); 646 - let fut = async move { (*inner).play(request).await }; 647 Box::pin(fut) 648 } 649 } 650 let accept_compression_encodings = self.accept_compression_encodings; 651 let send_compression_encodings = self.send_compression_encodings; 652 let inner = self.inner.clone(); 653 let fut = async move { 654 - let inner = inner.0; 655 let method = PlaySvc(inner); 656 let codec = tonic::codec::ProstCodec::default(); 657 let mut grpc = tonic::server::Grpc::new(codec) 658 .apply_compression_config( 659 accept_compression_encodings, 660 send_compression_encodings, 661 ); 662 let res = grpc.unary(method, req).await; 663 Ok(res) ··· 679 &mut self, 680 request: tonic::Request<super::StopRequest>, 681 ) -> Self::Future { 682 - let inner = self.0.clone(); 683 - let fut = async move { (*inner).stop(request).await }; 684 Box::pin(fut) 685 } 686 } 687 let accept_compression_encodings = self.accept_compression_encodings; 688 let send_compression_encodings = self.send_compression_encodings; 689 let inner = self.inner.clone(); 690 let fut = async move { 691 - let inner = inner.0; 692 let method = StopSvc(inner); 693 let codec = tonic::codec::ProstCodec::default(); 694 let mut grpc = tonic::server::Grpc::new(codec) 695 .apply_compression_config( 696 accept_compression_encodings, 697 send_compression_encodings, 698 ); 699 let res = grpc.unary(method, req).await; 700 Ok(res) ··· 717 &mut self, 718 request: tonic::Request<super::PlayOrPauseRequest>, 719 ) -> Self::Future { 720 - let inner = self.0.clone(); 721 let fut = async move { 722 - (*inner).play_or_pause(request).await 723 }; 724 Box::pin(fut) 725 } 726 } 727 let accept_compression_encodings = self.accept_compression_encodings; 728 let send_compression_encodings = self.send_compression_encodings; 729 let inner = self.inner.clone(); 730 let fut = async move { 731 - let inner = inner.0; 732 let method = PlayOrPauseSvc(inner); 733 let codec = tonic::codec::ProstCodec::default(); 734 let mut grpc = tonic::server::Grpc::new(codec) 735 .apply_compression_config( 736 accept_compression_encodings, 737 send_compression_encodings, 738 ); 739 let res = grpc.unary(method, req).await; 740 Ok(res) ··· 743 } 744 _ => { 745 Box::pin(async move { 746 - Ok( 747 - http::Response::builder() 748 - .status(200) 749 - .header("grpc-status", "12") 750 - .header("content-type", "application/grpc") 751 - .body(empty_body()) 752 - .unwrap(), 753 - ) 754 }) 755 } 756 } 757 } 758 } 759 - impl<T: PlaybackService> Clone for PlaybackServiceServer<T> { 760 fn clone(&self) -> Self { 761 let inner = self.inner.clone(); 762 Self { 763 inner, 764 accept_compression_encodings: self.accept_compression_encodings, 765 send_compression_encodings: self.send_compression_encodings, 766 } 767 } 768 } 769 - impl<T: PlaybackService> Clone for _Inner<T> { 770 - fn clone(&self) -> Self { 771 - Self(self.0.clone()) 772 - } 773 - } 774 - impl<T: std::fmt::Debug> std::fmt::Debug for _Inner<T> { 775 - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 776 - write!(f, "{:?}", self.0) 777 - } 778 - } 779 - impl<T: PlaybackService> tonic::server::NamedService for PlaybackServiceServer<T> { 780 - const NAME: &'static str = "tunein.v1alpha1.PlaybackService"; 781 } 782 }
··· 1 + // This file is @generated by prost-build. 2 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 3 pub struct GetCategoriesRequest {} 4 #[derive(Clone, PartialEq, ::prost::Message)] 5 pub struct GetCategoriesResponse { 6 #[prost(message, repeated, tag = "1")] 7 pub categories: ::prost::alloc::vec::Vec<super::super::objects::v1alpha1::Category>, 8 } 9 #[derive(Clone, PartialEq, ::prost::Message)] 10 pub struct BrowseCategoryRequest { 11 #[prost(string, tag = "1")] 12 pub category_id: ::prost::alloc::string::String, 13 } 14 #[derive(Clone, PartialEq, ::prost::Message)] 15 pub struct BrowseCategoryResponse { 16 #[prost(message, repeated, tag = "1")] 17 pub categories: ::prost::alloc::vec::Vec<super::super::objects::v1alpha1::Category>, 18 } 19 #[derive(Clone, PartialEq, ::prost::Message)] 20 pub struct GetStationDetailsRequest { 21 #[prost(string, tag = "1")] 22 pub id: ::prost::alloc::string::String, 23 } 24 #[derive(Clone, PartialEq, ::prost::Message)] 25 pub struct GetStationDetailsResponse { 26 #[prost(message, repeated, tag = "1")] ··· 30 } 31 /// Generated client implementations. 32 pub mod browse_service_client { 33 + #![allow( 34 + unused_variables, 35 + dead_code, 36 + missing_docs, 37 + clippy::wildcard_imports, 38 + clippy::let_unit_value, 39 + )] 40 use tonic::codegen::*; 41 use tonic::codegen::http::Uri; 42 #[derive(Debug, Clone)] ··· 47 /// Attempt to create a new client by connecting to a given endpoint. 48 pub async fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error> 49 where 50 + D: TryInto<tonic::transport::Endpoint>, 51 D::Error: Into<StdError>, 52 { 53 let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; ··· 58 where 59 T: tonic::client::GrpcService<tonic::body::BoxBody>, 60 T::Error: Into<StdError>, 61 + T::ResponseBody: Body<Data = Bytes> + std::marker::Send + 'static, 62 + <T::ResponseBody as Body>::Error: Into<StdError> + std::marker::Send, 63 { 64 pub fn new(inner: T) -> Self { 65 let inner = tonic::client::Grpc::new(inner); ··· 84 >, 85 <T as tonic::codegen::Service< 86 http::Request<tonic::body::BoxBody>, 87 + >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync, 88 { 89 BrowseServiceClient::new(InterceptedService::new(inner, interceptor)) 90 } ··· 103 self.inner = self.inner.accept_compressed(encoding); 104 self 105 } 106 + /// Limits the maximum size of a decoded message. 107 + /// 108 + /// Default: `4MB` 109 + #[must_use] 110 + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { 111 + self.inner = self.inner.max_decoding_message_size(limit); 112 + self 113 + } 114 + /// Limits the maximum size of an encoded message. 115 + /// 116 + /// Default: `usize::MAX` 117 + #[must_use] 118 + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { 119 + self.inner = self.inner.max_encoding_message_size(limit); 120 + self 121 + } 122 pub async fn get_categories( 123 &mut self, 124 request: impl tonic::IntoRequest<super::GetCategoriesRequest>, 125 + ) -> std::result::Result< 126 + tonic::Response<super::GetCategoriesResponse>, 127 + tonic::Status, 128 + > { 129 self.inner 130 .ready() 131 .await 132 .map_err(|e| { 133 + tonic::Status::unknown( 134 format!("Service was not ready: {}", e.into()), 135 ) 136 })?; ··· 138 let path = http::uri::PathAndQuery::from_static( 139 "/tunein.v1alpha1.BrowseService/GetCategories", 140 ); 141 + let mut req = request.into_request(); 142 + req.extensions_mut() 143 + .insert( 144 + GrpcMethod::new("tunein.v1alpha1.BrowseService", "GetCategories"), 145 + ); 146 + self.inner.unary(req, path, codec).await 147 } 148 pub async fn browse_category( 149 &mut self, 150 request: impl tonic::IntoRequest<super::BrowseCategoryRequest>, 151 + ) -> std::result::Result< 152 + tonic::Response<super::BrowseCategoryResponse>, 153 + tonic::Status, 154 + > { 155 self.inner 156 .ready() 157 .await 158 .map_err(|e| { 159 + tonic::Status::unknown( 160 format!("Service was not ready: {}", e.into()), 161 ) 162 })?; ··· 164 let path = http::uri::PathAndQuery::from_static( 165 "/tunein.v1alpha1.BrowseService/BrowseCategory", 166 ); 167 + let mut req = request.into_request(); 168 + req.extensions_mut() 169 + .insert( 170 + GrpcMethod::new("tunein.v1alpha1.BrowseService", "BrowseCategory"), 171 + ); 172 + self.inner.unary(req, path, codec).await 173 } 174 pub async fn get_station_details( 175 &mut self, 176 request: impl tonic::IntoRequest<super::GetStationDetailsRequest>, 177 + ) -> std::result::Result< 178 + tonic::Response<super::GetStationDetailsResponse>, 179 + tonic::Status, 180 + > { 181 self.inner 182 .ready() 183 .await 184 .map_err(|e| { 185 + tonic::Status::unknown( 186 format!("Service was not ready: {}", e.into()), 187 ) 188 })?; ··· 190 let path = http::uri::PathAndQuery::from_static( 191 "/tunein.v1alpha1.BrowseService/GetStationDetails", 192 ); 193 + let mut req = request.into_request(); 194 + req.extensions_mut() 195 + .insert( 196 + GrpcMethod::new("tunein.v1alpha1.BrowseService", "GetStationDetails"), 197 + ); 198 + self.inner.unary(req, path, codec).await 199 } 200 } 201 } 202 /// Generated server implementations. 203 pub mod browse_service_server { 204 + #![allow( 205 + unused_variables, 206 + dead_code, 207 + missing_docs, 208 + clippy::wildcard_imports, 209 + clippy::let_unit_value, 210 + )] 211 use tonic::codegen::*; 212 /// Generated trait containing gRPC methods that should be implemented for use with BrowseServiceServer. 213 #[async_trait] 214 + pub trait BrowseService: std::marker::Send + std::marker::Sync + 'static { 215 async fn get_categories( 216 &self, 217 request: tonic::Request<super::GetCategoriesRequest>, 218 + ) -> std::result::Result< 219 + tonic::Response<super::GetCategoriesResponse>, 220 + tonic::Status, 221 + >; 222 async fn browse_category( 223 &self, 224 request: tonic::Request<super::BrowseCategoryRequest>, 225 + ) -> std::result::Result< 226 + tonic::Response<super::BrowseCategoryResponse>, 227 + tonic::Status, 228 + >; 229 async fn get_station_details( 230 &self, 231 request: tonic::Request<super::GetStationDetailsRequest>, 232 + ) -> std::result::Result< 233 + tonic::Response<super::GetStationDetailsResponse>, 234 + tonic::Status, 235 + >; 236 } 237 #[derive(Debug)] 238 + pub struct BrowseServiceServer<T> { 239 + inner: Arc<T>, 240 accept_compression_encodings: EnabledCompressionEncodings, 241 send_compression_encodings: EnabledCompressionEncodings, 242 + max_decoding_message_size: Option<usize>, 243 + max_encoding_message_size: Option<usize>, 244 } 245 + impl<T> BrowseServiceServer<T> { 246 pub fn new(inner: T) -> Self { 247 Self::from_arc(Arc::new(inner)) 248 } 249 pub fn from_arc(inner: Arc<T>) -> Self { 250 Self { 251 inner, 252 accept_compression_encodings: Default::default(), 253 send_compression_encodings: Default::default(), 254 + max_decoding_message_size: None, 255 + max_encoding_message_size: None, 256 } 257 } 258 pub fn with_interceptor<F>( ··· 276 self.send_compression_encodings.enable(encoding); 277 self 278 } 279 + /// Limits the maximum size of a decoded message. 280 + /// 281 + /// Default: `4MB` 282 + #[must_use] 283 + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { 284 + self.max_decoding_message_size = Some(limit); 285 + self 286 + } 287 + /// Limits the maximum size of an encoded message. 288 + /// 289 + /// Default: `usize::MAX` 290 + #[must_use] 291 + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { 292 + self.max_encoding_message_size = Some(limit); 293 + self 294 + } 295 } 296 impl<T, B> tonic::codegen::Service<http::Request<B>> for BrowseServiceServer<T> 297 where 298 T: BrowseService, 299 + B: Body + std::marker::Send + 'static, 300 + B::Error: Into<StdError> + std::marker::Send + 'static, 301 { 302 type Response = http::Response<tonic::body::BoxBody>; 303 type Error = std::convert::Infallible; ··· 305 fn poll_ready( 306 &mut self, 307 _cx: &mut Context<'_>, 308 + ) -> Poll<std::result::Result<(), Self::Error>> { 309 Poll::Ready(Ok(())) 310 } 311 fn call(&mut self, req: http::Request<B>) -> Self::Future { 312 match req.uri().path() { 313 "/tunein.v1alpha1.BrowseService/GetCategories" => { 314 #[allow(non_camel_case_types)] ··· 326 &mut self, 327 request: tonic::Request<super::GetCategoriesRequest>, 328 ) -> Self::Future { 329 + let inner = Arc::clone(&self.0); 330 let fut = async move { 331 + <T as BrowseService>::get_categories(&inner, request).await 332 }; 333 Box::pin(fut) 334 } 335 } 336 let accept_compression_encodings = self.accept_compression_encodings; 337 let send_compression_encodings = self.send_compression_encodings; 338 + let max_decoding_message_size = self.max_decoding_message_size; 339 + let max_encoding_message_size = self.max_encoding_message_size; 340 let inner = self.inner.clone(); 341 let fut = async move { 342 let method = GetCategoriesSvc(inner); 343 let codec = tonic::codec::ProstCodec::default(); 344 let mut grpc = tonic::server::Grpc::new(codec) 345 .apply_compression_config( 346 accept_compression_encodings, 347 send_compression_encodings, 348 + ) 349 + .apply_max_message_size_config( 350 + max_decoding_message_size, 351 + max_encoding_message_size, 352 ); 353 let res = grpc.unary(method, req).await; 354 Ok(res) ··· 371 &mut self, 372 request: tonic::Request<super::BrowseCategoryRequest>, 373 ) -> Self::Future { 374 + let inner = Arc::clone(&self.0); 375 let fut = async move { 376 + <T as BrowseService>::browse_category(&inner, request).await 377 }; 378 Box::pin(fut) 379 } 380 } 381 let accept_compression_encodings = self.accept_compression_encodings; 382 let send_compression_encodings = self.send_compression_encodings; 383 + let max_decoding_message_size = self.max_decoding_message_size; 384 + let max_encoding_message_size = self.max_encoding_message_size; 385 let inner = self.inner.clone(); 386 let fut = async move { 387 let method = BrowseCategorySvc(inner); 388 let codec = tonic::codec::ProstCodec::default(); 389 let mut grpc = tonic::server::Grpc::new(codec) 390 .apply_compression_config( 391 accept_compression_encodings, 392 send_compression_encodings, 393 + ) 394 + .apply_max_message_size_config( 395 + max_decoding_message_size, 396 + max_encoding_message_size, 397 ); 398 let res = grpc.unary(method, req).await; 399 Ok(res) ··· 416 &mut self, 417 request: tonic::Request<super::GetStationDetailsRequest>, 418 ) -> Self::Future { 419 + let inner = Arc::clone(&self.0); 420 let fut = async move { 421 + <T as BrowseService>::get_station_details(&inner, request) 422 + .await 423 }; 424 Box::pin(fut) 425 } 426 } 427 let accept_compression_encodings = self.accept_compression_encodings; 428 let send_compression_encodings = self.send_compression_encodings; 429 + let max_decoding_message_size = self.max_decoding_message_size; 430 + let max_encoding_message_size = self.max_encoding_message_size; 431 let inner = self.inner.clone(); 432 let fut = async move { 433 let method = GetStationDetailsSvc(inner); 434 let codec = tonic::codec::ProstCodec::default(); 435 let mut grpc = tonic::server::Grpc::new(codec) 436 .apply_compression_config( 437 accept_compression_encodings, 438 send_compression_encodings, 439 + ) 440 + .apply_max_message_size_config( 441 + max_decoding_message_size, 442 + max_encoding_message_size, 443 ); 444 let res = grpc.unary(method, req).await; 445 Ok(res) ··· 448 } 449 _ => { 450 Box::pin(async move { 451 + let mut response = http::Response::new(empty_body()); 452 + let headers = response.headers_mut(); 453 + headers 454 + .insert( 455 + tonic::Status::GRPC_STATUS, 456 + (tonic::Code::Unimplemented as i32).into(), 457 + ); 458 + headers 459 + .insert( 460 + http::header::CONTENT_TYPE, 461 + tonic::metadata::GRPC_CONTENT_TYPE, 462 + ); 463 + Ok(response) 464 }) 465 } 466 } 467 } 468 } 469 + impl<T> Clone for BrowseServiceServer<T> { 470 fn clone(&self) -> Self { 471 let inner = self.inner.clone(); 472 Self { 473 inner, 474 accept_compression_encodings: self.accept_compression_encodings, 475 send_compression_encodings: self.send_compression_encodings, 476 + max_decoding_message_size: self.max_decoding_message_size, 477 + max_encoding_message_size: self.max_encoding_message_size, 478 } 479 } 480 } 481 + /// Generated gRPC service name 482 + pub const SERVICE_NAME: &str = "tunein.v1alpha1.BrowseService"; 483 + impl<T> tonic::server::NamedService for BrowseServiceServer<T> { 484 + const NAME: &'static str = SERVICE_NAME; 485 } 486 } 487 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 488 pub struct PlayOrPauseRequest {} 489 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 490 pub struct PlayOrPauseResponse {} 491 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 492 pub struct StopRequest {} 493 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 494 pub struct StopResponse {} 495 #[derive(Clone, PartialEq, ::prost::Message)] 496 pub struct PlayRequest { 497 #[prost(string, tag = "1")] 498 pub station_name_or_id: ::prost::alloc::string::String, 499 } 500 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 501 pub struct PlayResponse {} 502 /// Generated client implementations. 503 pub mod playback_service_client { 504 + #![allow( 505 + unused_variables, 506 + dead_code, 507 + missing_docs, 508 + clippy::wildcard_imports, 509 + clippy::let_unit_value, 510 + )] 511 use tonic::codegen::*; 512 use tonic::codegen::http::Uri; 513 #[derive(Debug, Clone)] ··· 518 /// Attempt to create a new client by connecting to a given endpoint. 519 pub async fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error> 520 where 521 + D: TryInto<tonic::transport::Endpoint>, 522 D::Error: Into<StdError>, 523 { 524 let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; ··· 529 where 530 T: tonic::client::GrpcService<tonic::body::BoxBody>, 531 T::Error: Into<StdError>, 532 + T::ResponseBody: Body<Data = Bytes> + std::marker::Send + 'static, 533 + <T::ResponseBody as Body>::Error: Into<StdError> + std::marker::Send, 534 { 535 pub fn new(inner: T) -> Self { 536 let inner = tonic::client::Grpc::new(inner); ··· 555 >, 556 <T as tonic::codegen::Service< 557 http::Request<tonic::body::BoxBody>, 558 + >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync, 559 { 560 PlaybackServiceClient::new(InterceptedService::new(inner, interceptor)) 561 } ··· 574 self.inner = self.inner.accept_compressed(encoding); 575 self 576 } 577 + /// Limits the maximum size of a decoded message. 578 + /// 579 + /// Default: `4MB` 580 + #[must_use] 581 + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { 582 + self.inner = self.inner.max_decoding_message_size(limit); 583 + self 584 + } 585 + /// Limits the maximum size of an encoded message. 586 + /// 587 + /// Default: `usize::MAX` 588 + #[must_use] 589 + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { 590 + self.inner = self.inner.max_encoding_message_size(limit); 591 + self 592 + } 593 pub async fn play( 594 &mut self, 595 request: impl tonic::IntoRequest<super::PlayRequest>, 596 + ) -> std::result::Result<tonic::Response<super::PlayResponse>, tonic::Status> { 597 self.inner 598 .ready() 599 .await 600 .map_err(|e| { 601 + tonic::Status::unknown( 602 format!("Service was not ready: {}", e.into()), 603 ) 604 })?; ··· 606 let path = http::uri::PathAndQuery::from_static( 607 "/tunein.v1alpha1.PlaybackService/Play", 608 ); 609 + let mut req = request.into_request(); 610 + req.extensions_mut() 611 + .insert(GrpcMethod::new("tunein.v1alpha1.PlaybackService", "Play")); 612 + self.inner.unary(req, path, codec).await 613 } 614 pub async fn stop( 615 &mut self, 616 request: impl tonic::IntoRequest<super::StopRequest>, 617 + ) -> std::result::Result<tonic::Response<super::StopResponse>, tonic::Status> { 618 self.inner 619 .ready() 620 .await 621 .map_err(|e| { 622 + tonic::Status::unknown( 623 format!("Service was not ready: {}", e.into()), 624 ) 625 })?; ··· 627 let path = http::uri::PathAndQuery::from_static( 628 "/tunein.v1alpha1.PlaybackService/Stop", 629 ); 630 + let mut req = request.into_request(); 631 + req.extensions_mut() 632 + .insert(GrpcMethod::new("tunein.v1alpha1.PlaybackService", "Stop")); 633 + self.inner.unary(req, path, codec).await 634 } 635 pub async fn play_or_pause( 636 &mut self, 637 request: impl tonic::IntoRequest<super::PlayOrPauseRequest>, 638 + ) -> std::result::Result< 639 + tonic::Response<super::PlayOrPauseResponse>, 640 + tonic::Status, 641 + > { 642 self.inner 643 .ready() 644 .await 645 .map_err(|e| { 646 + tonic::Status::unknown( 647 format!("Service was not ready: {}", e.into()), 648 ) 649 })?; ··· 651 let path = http::uri::PathAndQuery::from_static( 652 "/tunein.v1alpha1.PlaybackService/PlayOrPause", 653 ); 654 + let mut req = request.into_request(); 655 + req.extensions_mut() 656 + .insert( 657 + GrpcMethod::new("tunein.v1alpha1.PlaybackService", "PlayOrPause"), 658 + ); 659 + self.inner.unary(req, path, codec).await 660 } 661 } 662 } 663 /// Generated server implementations. 664 pub mod playback_service_server { 665 + #![allow( 666 + unused_variables, 667 + dead_code, 668 + missing_docs, 669 + clippy::wildcard_imports, 670 + clippy::let_unit_value, 671 + )] 672 use tonic::codegen::*; 673 /// Generated trait containing gRPC methods that should be implemented for use with PlaybackServiceServer. 674 #[async_trait] 675 + pub trait PlaybackService: std::marker::Send + std::marker::Sync + 'static { 676 async fn play( 677 &self, 678 request: tonic::Request<super::PlayRequest>, 679 + ) -> std::result::Result<tonic::Response<super::PlayResponse>, tonic::Status>; 680 async fn stop( 681 &self, 682 request: tonic::Request<super::StopRequest>, 683 + ) -> std::result::Result<tonic::Response<super::StopResponse>, tonic::Status>; 684 async fn play_or_pause( 685 &self, 686 request: tonic::Request<super::PlayOrPauseRequest>, 687 + ) -> std::result::Result< 688 + tonic::Response<super::PlayOrPauseResponse>, 689 + tonic::Status, 690 + >; 691 } 692 #[derive(Debug)] 693 + pub struct PlaybackServiceServer<T> { 694 + inner: Arc<T>, 695 accept_compression_encodings: EnabledCompressionEncodings, 696 send_compression_encodings: EnabledCompressionEncodings, 697 + max_decoding_message_size: Option<usize>, 698 + max_encoding_message_size: Option<usize>, 699 } 700 + impl<T> PlaybackServiceServer<T> { 701 pub fn new(inner: T) -> Self { 702 Self::from_arc(Arc::new(inner)) 703 } 704 pub fn from_arc(inner: Arc<T>) -> Self { 705 Self { 706 inner, 707 accept_compression_encodings: Default::default(), 708 send_compression_encodings: Default::default(), 709 + max_decoding_message_size: None, 710 + max_encoding_message_size: None, 711 } 712 } 713 pub fn with_interceptor<F>( ··· 731 self.send_compression_encodings.enable(encoding); 732 self 733 } 734 + /// Limits the maximum size of a decoded message. 735 + /// 736 + /// Default: `4MB` 737 + #[must_use] 738 + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { 739 + self.max_decoding_message_size = Some(limit); 740 + self 741 + } 742 + /// Limits the maximum size of an encoded message. 743 + /// 744 + /// Default: `usize::MAX` 745 + #[must_use] 746 + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { 747 + self.max_encoding_message_size = Some(limit); 748 + self 749 + } 750 } 751 impl<T, B> tonic::codegen::Service<http::Request<B>> for PlaybackServiceServer<T> 752 where 753 T: PlaybackService, 754 + B: Body + std::marker::Send + 'static, 755 + B::Error: Into<StdError> + std::marker::Send + 'static, 756 { 757 type Response = http::Response<tonic::body::BoxBody>; 758 type Error = std::convert::Infallible; ··· 760 fn poll_ready( 761 &mut self, 762 _cx: &mut Context<'_>, 763 + ) -> Poll<std::result::Result<(), Self::Error>> { 764 Poll::Ready(Ok(())) 765 } 766 fn call(&mut self, req: http::Request<B>) -> Self::Future { 767 match req.uri().path() { 768 "/tunein.v1alpha1.PlaybackService/Play" => { 769 #[allow(non_camel_case_types)] ··· 780 &mut self, 781 request: tonic::Request<super::PlayRequest>, 782 ) -> Self::Future { 783 + let inner = Arc::clone(&self.0); 784 + let fut = async move { 785 + <T as PlaybackService>::play(&inner, request).await 786 + }; 787 Box::pin(fut) 788 } 789 } 790 let accept_compression_encodings = self.accept_compression_encodings; 791 let send_compression_encodings = self.send_compression_encodings; 792 + let max_decoding_message_size = self.max_decoding_message_size; 793 + let max_encoding_message_size = self.max_encoding_message_size; 794 let inner = self.inner.clone(); 795 let fut = async move { 796 let method = PlaySvc(inner); 797 let codec = tonic::codec::ProstCodec::default(); 798 let mut grpc = tonic::server::Grpc::new(codec) 799 .apply_compression_config( 800 accept_compression_encodings, 801 send_compression_encodings, 802 + ) 803 + .apply_max_message_size_config( 804 + max_decoding_message_size, 805 + max_encoding_message_size, 806 ); 807 let res = grpc.unary(method, req).await; 808 Ok(res) ··· 824 &mut self, 825 request: tonic::Request<super::StopRequest>, 826 ) -> Self::Future { 827 + let inner = Arc::clone(&self.0); 828 + let fut = async move { 829 + <T as PlaybackService>::stop(&inner, request).await 830 + }; 831 Box::pin(fut) 832 } 833 } 834 let accept_compression_encodings = self.accept_compression_encodings; 835 let send_compression_encodings = self.send_compression_encodings; 836 + let max_decoding_message_size = self.max_decoding_message_size; 837 + let max_encoding_message_size = self.max_encoding_message_size; 838 let inner = self.inner.clone(); 839 let fut = async move { 840 let method = StopSvc(inner); 841 let codec = tonic::codec::ProstCodec::default(); 842 let mut grpc = tonic::server::Grpc::new(codec) 843 .apply_compression_config( 844 accept_compression_encodings, 845 send_compression_encodings, 846 + ) 847 + .apply_max_message_size_config( 848 + max_decoding_message_size, 849 + max_encoding_message_size, 850 ); 851 let res = grpc.unary(method, req).await; 852 Ok(res) ··· 869 &mut self, 870 request: tonic::Request<super::PlayOrPauseRequest>, 871 ) -> Self::Future { 872 + let inner = Arc::clone(&self.0); 873 let fut = async move { 874 + <T as PlaybackService>::play_or_pause(&inner, request).await 875 }; 876 Box::pin(fut) 877 } 878 } 879 let accept_compression_encodings = self.accept_compression_encodings; 880 let send_compression_encodings = self.send_compression_encodings; 881 + let max_decoding_message_size = self.max_decoding_message_size; 882 + let max_encoding_message_size = self.max_encoding_message_size; 883 let inner = self.inner.clone(); 884 let fut = async move { 885 let method = PlayOrPauseSvc(inner); 886 let codec = tonic::codec::ProstCodec::default(); 887 let mut grpc = tonic::server::Grpc::new(codec) 888 .apply_compression_config( 889 accept_compression_encodings, 890 send_compression_encodings, 891 + ) 892 + .apply_max_message_size_config( 893 + max_decoding_message_size, 894 + max_encoding_message_size, 895 ); 896 let res = grpc.unary(method, req).await; 897 Ok(res) ··· 900 } 901 _ => { 902 Box::pin(async move { 903 + let mut response = http::Response::new(empty_body()); 904 + let headers = response.headers_mut(); 905 + headers 906 + .insert( 907 + tonic::Status::GRPC_STATUS, 908 + (tonic::Code::Unimplemented as i32).into(), 909 + ); 910 + headers 911 + .insert( 912 + http::header::CONTENT_TYPE, 913 + tonic::metadata::GRPC_CONTENT_TYPE, 914 + ); 915 + Ok(response) 916 }) 917 } 918 } 919 } 920 } 921 + impl<T> Clone for PlaybackServiceServer<T> { 922 fn clone(&self) -> Self { 923 let inner = self.inner.clone(); 924 Self { 925 inner, 926 accept_compression_encodings: self.accept_compression_encodings, 927 send_compression_encodings: self.send_compression_encodings, 928 + max_decoding_message_size: self.max_decoding_message_size, 929 + max_encoding_message_size: self.max_encoding_message_size, 930 } 931 } 932 } 933 + /// Generated gRPC service name 934 + pub const SERVICE_NAME: &str = "tunein.v1alpha1.PlaybackService"; 935 + impl<T> tonic::server::NamedService for PlaybackServiceServer<T> { 936 + const NAME: &'static str = SERVICE_NAME; 937 } 938 }
+38
src/lib.rs
··· 1 pub mod api { 2 #[path = ""] 3 pub mod tunein { 4 use tunein::types::CategoryDetails; 5 6 use super::objects::v1alpha1::{Category, Station, StationLinkDetails}; 7 8 #[path = "tunein.v1alpha1.rs"] 9 pub mod v1alpha1; 10 impl From<CategoryDetails> for Category { 11 fn from(category: CategoryDetails) -> Self { 12 Self { ··· 45 .collect() 46 }) 47 .unwrap_or(vec![]), 48 } 49 } 50 }
··· 1 + pub mod extract; 2 + pub mod provider; 3 + pub mod types; 4 + 5 pub mod api { 6 #[path = ""] 7 pub mod tunein { 8 + use super::super::types; 9 use tunein::types::CategoryDetails; 10 11 use super::objects::v1alpha1::{Category, Station, StationLinkDetails}; 12 13 #[path = "tunein.v1alpha1.rs"] 14 pub mod v1alpha1; 15 + 16 + pub const FILE_DESCRIPTOR_SET: &[u8] = include_bytes!("api/descriptor.bin"); 17 + 18 + impl From<String> for Category { 19 + fn from(name: String) -> Self { 20 + Self { 21 + name, 22 + ..Default::default() 23 + } 24 + } 25 + } 26 + 27 + impl From<types::Station> for Category { 28 + fn from(st: crate::types::Station) -> Self { 29 + Self { 30 + id: st.id, 31 + name: st.name, 32 + ..Default::default() 33 + } 34 + } 35 + } 36 + 37 impl From<CategoryDetails> for Category { 38 fn from(category: CategoryDetails) -> Self { 39 Self { ··· 72 .collect() 73 }) 74 .unwrap_or(vec![]), 75 + } 76 + } 77 + } 78 + 79 + impl From<types::Station> for StationLinkDetails { 80 + fn from(s: types::Station) -> Self { 81 + Self { 82 + bitrate: s.bitrate, 83 + url: s.stream_url, 84 + media_type: s.codec, 85 + ..Default::default() 86 } 87 } 88 }
+27 -38
src/server/browse.rs
··· 1 - use std::str::FromStr; 2 - 3 - use tunein::{types, TuneInClient}; 4 use tunein_cli::api::{ 5 objects::v1alpha1::{Category, StationLinkDetails}, 6 tunein::v1alpha1::{ ··· 10 }, 11 }; 12 13 - pub struct Browse { 14 - client: TuneInClient, 15 - } 16 17 - impl Default for Browse { 18 - fn default() -> Self { 19 - Self { 20 - client: TuneInClient::new(), 21 - } 22 - } 23 - } 24 25 #[tonic::async_trait] 26 impl BrowseService for Browse { ··· 28 &self, 29 _request: tonic::Request<GetCategoriesRequest>, 30 ) -> Result<tonic::Response<GetCategoriesResponse>, tonic::Status> { 31 - let result = self 32 - .client 33 - .browse(None) 34 .await 35 .map_err(|e| tonic::Status::internal(e.to_string()))?; 36 ··· 45 ) -> Result<tonic::Response<BrowseCategoryResponse>, tonic::Status> { 46 let req = request.into_inner(); 47 let category_id = req.category_id; 48 - let categories: Vec<Category> = match types::Category::from_str(&category_id) { 49 - Ok(category) => { 50 - let results = self 51 - .client 52 - .browse(Some(category)) 53 - .await 54 - .map_err(|e| tonic::Status::internal(e.to_string()))?; 55 - results.into_iter().map(Category::from).collect() 56 - } 57 - Err(_) => { 58 - let results = self 59 - .client 60 - .browse_by_id(&category_id) 61 - .await 62 - .map_err(|e| tonic::Status::internal(e.to_string()))?; 63 - results.into_iter().map(Category::from).collect() 64 - } 65 - }; 66 Ok(tonic::Response::new(BrowseCategoryResponse { categories })) 67 } 68 ··· 72 ) -> Result<tonic::Response<GetStationDetailsResponse>, tonic::Status> { 73 let req = request.into_inner(); 74 let station_id = req.id; 75 - let station = self 76 - .client 77 - .get_station(&station_id) 78 .await 79 .map_err(|e| tonic::Status::internal(e.to_string()))?; 80 81 Ok(tonic::Response::new(GetStationDetailsResponse { 82 - station_link_details: station.into_iter().map(StationLinkDetails::from).collect(), 83 })) 84 } 85 }
··· 1 use tunein_cli::api::{ 2 objects::v1alpha1::{Category, StationLinkDetails}, 3 tunein::v1alpha1::{ ··· 7 }, 8 }; 9 10 + use tunein_cli::provider::{tunein::Tunein, Provider}; 11 12 + #[derive(Default)] 13 + pub struct Browse; 14 15 #[tonic::async_trait] 16 impl BrowseService for Browse { ··· 18 &self, 19 _request: tonic::Request<GetCategoriesRequest>, 20 ) -> Result<tonic::Response<GetCategoriesResponse>, tonic::Status> { 21 + let client: Box<dyn Provider + Send + Sync> = Box::new(Tunein::new()); 22 + let offset = 0; 23 + let limit = 100; 24 + let result = client 25 + .categories(offset, limit) 26 .await 27 .map_err(|e| tonic::Status::internal(e.to_string()))?; 28 ··· 37 ) -> Result<tonic::Response<BrowseCategoryResponse>, tonic::Status> { 38 let req = request.into_inner(); 39 let category_id = req.category_id; 40 + 41 + let offset = 0; 42 + let limit = 100; 43 + 44 + let client: Box<dyn Provider + Send + Sync> = Box::new(Tunein::new()); 45 + let results = client 46 + .browse(category_id, offset, limit) 47 + .await 48 + .map_err(|e| tonic::Status::internal(e.to_string()))?; 49 + 50 + let categories = results.into_iter().map(Category::from).collect(); 51 Ok(tonic::Response::new(BrowseCategoryResponse { categories })) 52 } 53 ··· 57 ) -> Result<tonic::Response<GetStationDetailsResponse>, tonic::Status> { 58 let req = request.into_inner(); 59 let station_id = req.id; 60 + let client: Box<dyn Provider + Send + Sync> = Box::new(Tunein::new()); 61 + let result = client 62 + .get_station(station_id) 63 .await 64 .map_err(|e| tonic::Status::internal(e.to_string()))?; 65 66 + let station = match result { 67 + Some(station) => station, 68 + None => return Err(tonic::Status::internal("No station found")), 69 + }; 70 Ok(tonic::Response::new(GetStationDetailsResponse { 71 + station_link_details: vec![StationLinkDetails::from(station)], 72 })) 73 } 74 }
+6
src/server/mod.rs
··· 6 use tunein_cli::api::tunein::v1alpha1::{ 7 browse_service_server::BrowseServiceServer, playback_service_server::PlaybackServiceServer, 8 }; 9 10 use self::{browse::Browse, playback::Playback}; 11 ··· 17 println!("Listening on {}", addr.cyan()); 18 Server::builder() 19 .accept_http1(true) 20 .add_service(tonic_web::enable(BrowseServiceServer::new( 21 Browse::default(), 22 )))
··· 6 use tunein_cli::api::tunein::v1alpha1::{ 7 browse_service_server::BrowseServiceServer, playback_service_server::PlaybackServiceServer, 8 }; 9 + use tunein_cli::api::tunein::FILE_DESCRIPTOR_SET; 10 11 use self::{browse::Browse, playback::Playback}; 12 ··· 18 println!("Listening on {}", addr.cyan()); 19 Server::builder() 20 .accept_http1(true) 21 + .add_service( 22 + tonic_reflection::server::Builder::configure() 23 + .register_encoded_file_descriptor_set(FILE_DESCRIPTOR_SET) 24 + .build_v1alpha()?, 25 + ) 26 .add_service(tonic_web::enable(BrowseServiceServer::new( 27 Browse::default(), 28 )))
+12 -51
src/server/playback.rs
··· 1 use std::sync::{Arc, Mutex}; 2 3 use tokio::sync::mpsc; 4 - use tunein::TuneInClient; 5 use tunein_cli::api::tunein::v1alpha1::{ 6 playback_service_server::PlaybackService, PlayOrPauseRequest, PlayOrPauseResponse, PlayRequest, 7 PlayResponse, StopRequest, StopResponse, 8 }; 9 10 use crate::{ 11 - extract::extract_stream_url, 12 player::{Player, PlayerCommand}, 13 }; 14 15 pub struct Playback { 16 - client: TuneInClient, 17 player: Player, 18 cmd_tx: mpsc::UnboundedSender<PlayerCommand>, 19 } ··· 23 let (cmd_tx, cmd_rx) = mpsc::unbounded_channel::<PlayerCommand>(); 24 let cmd_rx = Arc::new(Mutex::new(cmd_rx)); 25 let player = Player::new(cmd_rx); 26 - Self { 27 - client: TuneInClient::new(), 28 - player, 29 - cmd_tx, 30 - } 31 } 32 } 33 ··· 39 ) -> Result<tonic::Response<PlayResponse>, tonic::Status> { 40 let req = request.into_inner(); 41 42 - let results = self 43 - .client 44 - .get_station(&req.station_name_or_id) 45 .await 46 .map_err(|e| tonic::Status::internal(e.to_string()))?; 47 - let (url, playlist_type, _) = match results.is_empty() { 48 - true => { 49 - let results = self 50 - .client 51 - .search(&req.station_name_or_id) 52 - .await 53 - .map_err(|e| tonic::Status::internal(e.to_string()))?; 54 - match results.first() { 55 - Some(result) => { 56 - if result.r#type != Some("audio".to_string()) { 57 - return Err(tonic::Status::internal("No station found")); 58 - } 59 - let id = result.guide_id.as_ref().unwrap(); 60 - let station = self 61 - .client 62 - .get_station(id) 63 - .await 64 - .map_err(|e| tonic::Status::internal(e.to_string()))?; 65 - let station = station.first().unwrap(); 66 - ( 67 - station.url.clone(), 68 - station.playlist_type.clone(), 69 - station.media_type.clone(), 70 - ) 71 - } 72 - None => ("".to_string(), None, "".to_string()), 73 - } 74 - } 75 - false => { 76 - let result = results.first().unwrap(); 77 - ( 78 - result.url.clone(), 79 - result.playlist_type.clone(), 80 - result.media_type.clone(), 81 - ) 82 - } 83 - }; 84 - let stream_url = extract_stream_url(&url, playlist_type) 85 - .await 86 - .map_err(|e| tonic::Status::internal(e.to_string()))?; 87 println!("{}", stream_url); 88 89 self.cmd_tx.send(PlayerCommand::Play(stream_url)).unwrap();
··· 1 use std::sync::{Arc, Mutex}; 2 3 use tokio::sync::mpsc; 4 use tunein_cli::api::tunein::v1alpha1::{ 5 playback_service_server::PlaybackService, PlayOrPauseRequest, PlayOrPauseResponse, PlayRequest, 6 PlayResponse, StopRequest, StopResponse, 7 }; 8 9 use crate::{ 10 player::{Player, PlayerCommand}, 11 + provider::{tunein::Tunein, Provider}, 12 }; 13 14 pub struct Playback { 15 player: Player, 16 cmd_tx: mpsc::UnboundedSender<PlayerCommand>, 17 } ··· 21 let (cmd_tx, cmd_rx) = mpsc::unbounded_channel::<PlayerCommand>(); 22 let cmd_rx = Arc::new(Mutex::new(cmd_rx)); 23 let player = Player::new(cmd_rx); 24 + Self { player, cmd_tx } 25 } 26 } 27 ··· 33 ) -> Result<tonic::Response<PlayResponse>, tonic::Status> { 34 let req = request.into_inner(); 35 36 + let client: Box<dyn Provider + Send + Sync> = Box::new(Tunein::new()); 37 + let station = client 38 + .get_station(req.station_name_or_id.clone()) 39 .await 40 .map_err(|e| tonic::Status::internal(e.to_string()))?; 41 + 42 + if station.is_none() { 43 + return Err(tonic::Status::internal("No station found")); 44 + } 45 + 46 + let station = station.unwrap(); 47 + let stream_url = station.stream_url.clone(); 48 println!("{}", stream_url); 49 50 self.cmd_tx.send(PlayerCommand::Play(stream_url)).unwrap();