{"id":19333572,"url":"https://github.com/ebkalderon/dss-coding-assignment","last_synced_at":"2025-08-02T17:11:45.651Z","repository":{"id":81120255,"uuid":"330761309","full_name":"ebkalderon/dss-coding-assignment","owner":"ebkalderon","description":"Interactive media navigation menu populated by JSON API","archived":false,"fork":false,"pushed_at":"2021-03-29T03:41:48.000Z","size":2469,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-06T09:12:02.568Z","etag":null,"topics":["coding-assignment"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ebkalderon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-01-18T19:03:41.000Z","updated_at":"2021-06-12T06:21:38.000Z","dependencies_parsed_at":null,"dependency_job_id":"fce97d20-30cc-454d-a52b-128363ec30af","html_url":"https://github.com/ebkalderon/dss-coding-assignment","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ebkalderon%2Fdss-coding-assignment","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ebkalderon%2Fdss-coding-assignment/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ebkalderon%2Fdss-coding-assignment/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ebkalderon%2Fdss-coding-assignment/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ebkalderon","download_url":"https://codeload.github.com/ebkalderon/dss-coding-assignment/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240435046,"owners_count":19800722,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["coding-assignment"],"created_at":"2024-11-10T02:53:35.276Z","updated_at":"2025-02-24T07:23:27.168Z","avatar_url":"https://github.com/ebkalderon.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Disney Streaming Services (DSS) Main Menu\n\nMain menu for a DSS-inspired streaming media application, written in Rust.\n\n![Screenshot](./screenshot.png)\n\n## Getting started\n\nTo build this project on Windows, macOS, or Linux, you will need a recent\nversion of the [Rust toolchain](https://www.rust-lang.org/) at least version\n1.46.0, at minimum, but versions 1.48.0 and newer are strongly recommended\nbecause they perform better with async code ([rust-lang/rust#78410]).\n\n[rust-lang/rust#78410]: https://github.com/rust-lang/rust/pull/78410\n\nIf [`rustup`](https://rustup.rs/) is available on your system, the included \n[`rust-toolchain`](./rust-toolchain) file at the root directory of this\nrepository should automatically fetch and install the Rust toolchain for you, if\nnot already present on your system, as soon as you execute any `cargo` command\nin the shell.\n\nThe following external dependencies will also be required on your system:\n\n* [SDL2], for system window and render context management, input handling, and\n  hardware-accelerated rendering.\n* [SDL2_image], for loading arbitrary image files as SDL textures.\n* [SDL2_ttf], for loading and rendering TrueType fonts as SDL textures.\n\n[SDL2]: https://www.libsdl.org/\n[SDL2_image]: https://www.libsdl.org/projects/SDL_image/\n[SDL2_ttf]: https://www.libsdl.org/projects/SDL_ttf/\n\n### Windows (MSVC with vcpkg)\n\n```bat\nvcpkg.exe install sdl2:x64-windows sdl2-image:x64-windows sdl2-ttf:x64-windows\n```\n\n### macOS\n\n```bash\nbrew install sdl2 sdl2_image sdl2_ttf\n```\n\n### Linux\n\n```bash\n# Ubuntu/Debian\nsudo apt install libsdl2 libsdl2-image libsdl2-ttf\n\n# Arch Linux\nsudo pacman -Sy sdl2 sdl2_image sdl2_ttf\n```\n\n## Compiling\n\nTo compile the application in release mode and start it, simply run this command\nin your terminal:\n\n```bash\ncargo run --release\n```\n\nTo execute the included unit test suite, run:\n\n```bash\ncargo test\n```\n\nTo generate HTML documentation for the public crate API, run:\n\n```bash\ncargo doc --open\n```\n\n## Usage\n\nThe input controls for navigating the UI are listed below:\n\nAction            | Controls\n------------------|-------------------------------------------------------------\nNavigate menu     | \u003ckbd\u003e↑\u003c/kbd\u003e, \u003ckbd\u003e↓\u003c/kbd\u003e, \u003ckbd\u003e←\u003c/kbd\u003e, \u003ckbd\u003e→\u003c/kbd\u003e\nToggle fullscreen | \u003ckbd\u003eF11\u003c/kbd\u003e\nClose window      | \u003ckbd\u003eEsc\u003c/kbd\u003e or \"close\" button\n\n## Project layout\n\nLike many idiomatic Rust projects, this service is split into a binary crate\n(the `main.rs` file) and a library crate (`lib.rs` and the rest). This is to\nfacilitate simpler unit and integration testing under Cargo, should we require\nmore of it in the future.\n\nThe `main.rs` is a very thin shim over `dss_menu::app::App`, which manages the\nmain loop, UI rendering, and drives the `dss_menu::menu::Menu` business logic\nforward.\n\nThere is also a single background I/O thread for fetching arbitrary files over\nHTTP and caching them in the OS temp directory, which is spawned on app startup;\nthe implementation for this is located in `src/fetcher.rs`. This thread can\nprocess many async HTTP downloads concurrently without resorting to spawning one\nthread per connection, and sends completed files back to the main thread as they\nbecome available.\n\nThe JSON schema `serde` types are located in `src/schema.rs` and its submodules.\n\n## Assumptions\n\n* This application will run on an OS with a system allocator available.\n\n* This class of application is optimized for mobile devices or smart TVs, and as\n  such should try to eliminate heap allocation and dynamic dispatch where\n  possible, and also put the CPU to sleep when applicable to consume less power.\n\n* This application will fetch and stream resources from the Internet as they\n  become available while avoiding blocking the main loop, and may require some\n  form of async concurrency in order to scale efficiently without spawning more\n  than two OS threads, one for the application and another for network I/O.\n\n* Cached files will not persist in between individual runs of the application.\n\n## Possible improvements\n\n* Dynamically populate ref sets as they scroll into view (didn't quite have time\n  to build a widget or callback for that). We are capable of parsing this data,\n  though, since the schema types exist.\n\n* Draw rectangular cursor of selected menu tile with rounded corners.\n\n* Implement animations by passing the delta time between frames to\n  `Widget::update()` and using linear interpolation in `Menu::select_tile()` to\n  gradually select and deselect tiles.\n\n* Load the video art MP4 files for use as background animations for the\n  currently selected tile.\n\n* Skip the SDL hardware-accelerated rendering context and offload even more\n  manual rendering computations from the CPU to the GPU.\n\n* Cache individually rendered TTF glyphs as SDL textures to make repeated text\n  rendering faster, a la [grimfang4/SDL_FontCache].\n\n* Find (or write) an alternative async executor which allows for explicit\n  handling of out-of-memory errors.\n\n* Try to reduce heap allocations by using `serde` in zero-copy deserialization\n  mode and adding a lifetime to the `home.json` AST (thereby using `\u0026str` over\n  `String` when possible).\n\n* Perhaps the number of `String` and `Url` copies made during file fetching and\n  polling could be reduced by sending references instead of values over the\n  channel, but this would be really tedious to implement due to lifetimes, to\n  say the least.\n\n* Add text logging and/or profiling with [Criterion.rs] and `cargo bench`.\n\n* Change `App` to contain a stack of `State`s, rather than just one, and\n  implement a pushdown automaton with switch/push/pop state transitions to\n  create modal interfaces and other screens.\n\n## Third-party Rust libraries\n\n* `anyhow` is used to eliminate boilerplate from error handling. This commonly\n   used crate eliminates the need to create your own error struct or enum for\n   application-type Rust projects (as opposed to library-type projects, where\n   `thiserror` is more popular) and reduces the number of manual implementations\n   of `Debug`, `Display`, `From`, and `std::error::Error` as well as conversions\n   between them.\n\n* `flume` is a MPMC channel library that fixes numerous bugs and deficiencies\n  seen in `std::sync::mpsc`, and most notably works with mixed sync/async code.\n  This library is used for passing data between the synchronous rendering thread\n  and the asynchronous background I/O thread without blocking the main loop.\n\n* `fnv` provides a faster and cheaper hashing algorithm than the Rust standard\n  library, which is intended to be DoS resistant by default. We don't need this\n  protection for local rendering uses, though, and `fnv` performs _way_ better\n  during hot loops where map accesses and inserts are frequent.\n\n* `futures-util` contains common async traits not yet available in the Rust\n  standard library (e.g. `FutureExt`, `StreamExt`, and so on) as well as the\n  `Abortable` combinator and `poll_fn()` function used in tests.\n\n* `sdl2` provides native Rust bindings to SDL 2.0, as well as `SDL_image` and\n  `SDL_ttf` for image loading and font rendering, respectively.\n\n* `serde` and `serde_json` provide JSON deserialization with pretty good\n  performance for consuming the DSS `home.json` API.\n\n* `reqwest` is an async HTTP client used for fetching JSON and image files from\n  the DSS API while the main thread is busy rendering. It happens to include\n  `rustls` as an optional statically-linked pure Rust alternative to OpenSSL,\n  which is nice because it eliminates one more runtime dependency and\n  [uses less memory].\n\n* `tempfile` is used for locating the OS temporary directory and creating\n  temporary files that delete themselves after dropping, a facility not provided\n  by the Rust standard library.\n\n* `tokio` is used to spawn multiple async tasks and join them concurrently while\n  using minimal resources. Although Rust provides zero-cost async (in the C++\n  sense), it does not include an executor in the standard library to drive those\n  futures, requiring users to choose one from Crates.io or write their own\n  instead. This crate is compiled in single-threaded mode to stay lightweight.\n\n* `url` is used for parsing URL values from strings, both at deserialization\n  time and for use with `reqwest`.\n\n* `uuid` is used only for type-safety while deserializing UUIDs from JSON.\n\n[uses less memory]: https://jbp.io/2019/07/01/rustls-vs-openssl-performance.html\n[grimfang4/SDL_FontCache]: https://github.com/grimfang4/SDL_FontCache\n[Criterion.rs]: https://bheisler.github.io/criterion.rs/book/criterion_rs.html\n\n## Credits\n\nIncludes the [Cocogoose Pro] TrueType font family, which is free for personal\nuse.\n\n[Cocogoose Pro]: https://www.1001fonts.com/cocogoose-pro-font.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Febkalderon%2Fdss-coding-assignment","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Febkalderon%2Fdss-coding-assignment","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Febkalderon%2Fdss-coding-assignment/lists"}