Skip to content

Commit 22e6cab

Browse files
authored
Rewrite the API (#44)
This rewrite has the following goals: - Remove code that is unrelated to storing frame data, such as the `math` module - Rework the public interface to focus on visible pixels first, rather than including padding first - This includes hiding access to padding data behind a Cargo feature - Ensure that data access is safe and performant - This is enabled by making sure we limit the number of ways to instantiate a frame, and that those ways are thoroughly validated. Currently the only way to initialize a `Frame` or `Plane`s is through the `FrameBuilder` interface. - We want to avoid the current pattern where API users are accessing the raw data and using `unsafe` blocks to manually iterate over the visible pixels. Users should feel comfortable that v_frame's accessors are performant.
1 parent c21abb1 commit 22e6cab

File tree

18 files changed

+2657
-1991
lines changed

18 files changed

+2657
-1991
lines changed

.github/dependabot.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "cargo"
4+
directory: "/"
5+
schedule:
6+
interval: "weekly"
7+
open-pull-requests-limit: 5
8+
commit-message:
9+
prefix: "chore"
10+
include: "scope"
11+
labels:
12+
- "dependencies"
13+
- "rust"
14+
groups:
15+
rust-dependencies:
16+
patterns:
17+
- "*"
18+
update-types:
19+
- "minor"
20+
- "patch"
21+
- package-ecosystem: "github-actions"
22+
directory: "/"
23+
schedule:
24+
interval: "weekly"

.github/workflows/crate.yml

Lines changed: 64 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,86 +2,106 @@ name: Crate
22

33
on:
44
push:
5-
branches: [ "main" ]
5+
branches: ["main"]
66
pull_request:
7-
branches: [ "main" ]
8-
9-
env:
10-
CARGO_TERM_COLOR: always
11-
CARGO_INCREMENTAL: 0
7+
branches: ["main"]
128

139
jobs:
14-
build:
10+
format:
1511
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
- uses: dtolnay/rust-toolchain@stable
15+
with:
16+
components: rustfmt
17+
- name: Check formatting
18+
run: cargo fmt --all -- --check
1619

20+
clippy:
21+
runs-on: ubuntu-latest
1722
steps:
1823
- uses: actions/checkout@v4
19-
- name: Build
20-
run: cargo clippy
21-
- name: Run tests
22-
run: cargo test
24+
- uses: dtolnay/rust-toolchain@stable
25+
with:
26+
components: clippy
27+
- uses: Swatinem/rust-cache@v2
28+
- name: Run clippy (default features)
29+
run: cargo clippy --all-targets -- -D warnings
30+
- name: Run clippy (padding_api feature)
31+
run: cargo clippy --all-targets --features padding_api -- -D warnings
32+
33+
test:
34+
runs-on: ubuntu-latest
35+
steps:
36+
- uses: actions/checkout@v4
37+
- uses: dtolnay/rust-toolchain@stable
38+
- uses: Swatinem/rust-cache@v2
39+
- name: Run tests (default features)
40+
run: cargo test --all-targets
41+
- name: Run tests (padding_api feature)
42+
run: cargo test --all-targets --features padding_api
43+
44+
msrv:
45+
runs-on: ubuntu-latest
46+
steps:
47+
- uses: actions/checkout@v4
48+
- uses: dtolnay/rust-toolchain@stable
49+
- uses: Swatinem/rust-cache@v2
2350
- name: Install cargo-msrv
2451
uses: taiki-e/install-action@v2
2552
with:
2653
tool: cargo-msrv
2754
- name: Validate minimum Rust version
28-
run: |
29-
cargo msrv verify
55+
run: cargo msrv verify
3056

3157
test-wasm:
3258
runs-on: ubuntu-latest
33-
59+
strategy:
60+
matrix:
61+
features: ["", "padding_api"]
3462
steps:
3563
- uses: actions/checkout@v4
3664
- uses: dtolnay/rust-toolchain@stable
3765
with:
3866
targets: wasm32-unknown-unknown
39-
67+
- uses: Swatinem/rust-cache@v2
4068
- name: Install wasm-pack
4169
uses: taiki-e/install-action@v2
4270
with:
4371
tool: wasm-pack
44-
45-
- name: Run tests
46-
run: wasm-pack test --headless --chrome --firefox
47-
48-
miri:
49-
runs-on: ubuntu-latest
50-
51-
steps:
52-
- uses: actions/checkout@v4
53-
54-
- name: Install Rust nightly and miri
55-
uses: dtolnay/rust-toolchain@nightly
56-
with:
57-
components: miri, rust-src
58-
59-
- name: Run miri
60-
env:
61-
RUSTFLAGS: -Zrandomize-layout
62-
MIRIFLAGS: -Zmiri-symbolic-alignment-check
63-
run: cargo miri test
72+
- name: Run WASM tests${{ matrix.features && format(' ({0})', matrix.features) || '' }}
73+
run: wasm-pack test --headless --chrome --firefox ${{ matrix.features && format('--features {0}', matrix.features) || '' }}
74+
75+
# Disabling miri for now since it seems to be really, really slow
76+
# We should run it manually instead of on every CI run
77+
# miri:
78+
# runs-on: ubuntu-latest
79+
# steps:
80+
# - uses: actions/checkout@v4
81+
# - uses: dtolnay/rust-toolchain@nightly
82+
# with:
83+
# components: miri, rust-src
84+
# - uses: Swatinem/rust-cache@v2
85+
# - name: Run miri
86+
# env:
87+
# RUSTFLAGS: -Zrandomize-layout
88+
# MIRIFLAGS: -Zmiri-symbolic-alignment-check
89+
# run: cargo miri test --features padding_api
6490

6591
code-coverage:
66-
needs: [ miri, build ]
6792
runs-on: ubuntu-latest
68-
6993
steps:
7094
- uses: actions/checkout@v4
71-
72-
- name: Install Rust stable and LLVM tools
73-
uses: dtolnay/rust-toolchain@stable
95+
- uses: dtolnay/rust-toolchain@stable
7496
with:
7597
components: llvm-tools-preview
76-
98+
- uses: Swatinem/rust-cache@v2
7799
- name: Install cargo-llvm-cov
78100
uses: taiki-e/install-action@v2
79101
with:
80102
tool: cargo-llvm-cov
81-
82103
- name: Generate code coverage
83-
run: cargo llvm-cov --lcov --output-path lcov.log
84-
104+
run: cargo llvm-cov --all-targets --features padding_api --lcov --output-path lcov.log
85105
- name: Upload coverage to Codecov
86106
uses: codecov/codecov-action@v5
87107
with:

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
11
/target
22
/Cargo.lock
3+
/.vscode
4+
lcov.info
5+
CLAUDE.md
6+
.claude

Cargo.toml

Lines changed: 148 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,24 @@
11
[package]
22
name = "v_frame"
3-
version = "0.3.9"
4-
rust-version = "1.80.0"
3+
version = "0.4.0"
4+
rust-version = "1.85.0"
55
description = "Video Frame data structures, originally part of rav1e"
66
license = "BSD-2-Clause"
7-
authors = ["Luca Barbato <lu_zero@gentoo.org>"]
8-
edition = "2021"
7+
edition = "2024"
98
repository = "https://github.com/rust-av/v_frame"
10-
11-
[features]
12-
serialize = ["serde", "aligned-vec/serde"]
13-
profiling = ["dep:profiling"]
14-
tracing = ["profiling", "dep:tracing", "profiling/profile-with-tracing"]
9+
include = ["Cargo.toml", "README.md", "LICENSE", "src"]
1510

1611
[dependencies]
17-
num-traits = "0.2"
18-
serde = { version = "1.0", features = ["derive"], optional = true }
19-
aligned-vec = ">=0.5.0, <0.7"
12+
aligned-vec = "0.6.4"
13+
num-traits = "0.2.19"
14+
thiserror = "2.0.17"
2015

21-
# Profiling dependencies
22-
profiling = { version = "1", optional = true }
23-
tracing = { version = "0.1.40", optional = true }
16+
[features]
17+
padding_api = []
2418

25-
[[bench]]
26-
name = "bench"
27-
harness = false
19+
# Non-WASM targets use criterion with all default features (including rayon)
20+
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
21+
criterion = "0.6"
2822

2923
#
3024
# WebAssembly/wasm32 target support below
@@ -43,17 +37,145 @@ harness = false
4337
# - explicit targetting for wasm32-unknown-unknown or wasm32-wasi.
4438
# In Cargo.toml, this is done via [target.<target-triple>.dependencies]
4539
# In code, this is done via cfg(all(target_arch = "wasm32", target_os = "wasi"/"unknown"))
46-
47-
# The rayon feature does not work on any wasm32 target
48-
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
49-
criterion = "0.6"
50-
51-
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
52-
criterion = { version = "0.6", default-features = false }
53-
5440
# wasm-bindgen is only needed for wasm32-unknown-unknown and not other wasm32 targets
5541
[target.wasm32-unknown-unknown.dependencies]
5642
wasm-bindgen = "0.2"
5743

5844
[target.wasm32-unknown-unknown.dev-dependencies]
5945
wasm-bindgen-test = "0.3"
46+
# Disable rayon feature for WASM compatibility
47+
criterion = { version = "0.6", default-features = false, features = ["plotters", "cargo_bench_support"] }
48+
49+
[target.wasm32-wasi.dev-dependencies]
50+
# Disable rayon feature for WASM compatibility
51+
criterion = { version = "0.6", default-features = false, features = ["plotters", "cargo_bench_support"] }
52+
53+
[[bench]]
54+
name = "plane"
55+
harness = false
56+
57+
[lints.rust]
58+
missing_docs = "warn"
59+
60+
[lints.clippy]
61+
# Performance
62+
clear_with_drain = "warn"
63+
format_collect = "warn"
64+
format_push_string = "warn"
65+
imprecise_flops = "warn"
66+
inefficient_to_string = "warn"
67+
inline_always = "warn"
68+
iter_with_drain = "warn"
69+
large_include_file = "warn"
70+
large_types_passed_by_value = "warn"
71+
linkedlist = "deny"
72+
missing_inline_in_public_items = "warn"
73+
mutex_atomic = "warn"
74+
mutex_integer = "warn"
75+
naive_bytecount = "warn"
76+
needless_bitwise_bool = "warn"
77+
needless_collect = "warn"
78+
needless_pass_by_value = "warn"
79+
non_std_lazy_statics = "warn"
80+
non_zero_suggestions = "warn"
81+
or_fun_call = "warn"
82+
rc_buffer = "warn"
83+
redundant_clone = "warn"
84+
ref_option = "warn"
85+
set_contains_or_insert = "warn"
86+
stable_sort_primitive = "warn"
87+
string_lit_chars_any = "warn"
88+
suboptimal_flops = "warn"
89+
trivial_regex = "warn"
90+
trivially_copy_pass_by_ref = "warn"
91+
unnecessary_box_returns = "warn"
92+
unnecessary_join = "warn"
93+
unused_async = "warn"
94+
verbose_file_reads = "warn"
95+
# Readability/Code Intention
96+
allow_attributes = "warn"
97+
checked_conversions = "warn"
98+
clone_on_ref_ptr = "warn"
99+
cloned_instead_of_copied = "warn"
100+
enum_glob_use = "warn"
101+
equatable_if_let = "warn"
102+
filter_map_next = "warn"
103+
flat_map_option = "warn"
104+
if_then_some_else_none = "warn"
105+
implicit_clone = "warn"
106+
inconsistent_struct_constructor = "warn"
107+
invalid_upcast_comparisons = "warn"
108+
iter_filter_is_ok = "warn"
109+
iter_filter_is_some = "warn"
110+
iter_on_empty_collections = "warn"
111+
iter_on_single_items = "warn"
112+
macro_use_imports = "warn"
113+
manual_assert = "warn"
114+
manual_instant_elapsed = "warn"
115+
manual_is_power_of_two = "warn"
116+
manual_is_variant_and = "warn"
117+
manual_let_else = "warn"
118+
manual_string_new = "warn"
119+
map_unwrap_or = "warn"
120+
map_with_unused_argument_over_ranges = "warn"
121+
match_bool = "warn"
122+
mod_module_files = "warn"
123+
needless_continue = "warn"
124+
needless_pass_by_ref_mut = "warn"
125+
option_as_ref_cloned = "warn"
126+
option_if_let_else = "warn"
127+
pathbuf_init_then_push = "warn"
128+
precedence_bits = "warn"
129+
range_minus_one = "warn"
130+
range_plus_one = "warn"
131+
redundant_test_prefix = "warn"
132+
ref_option_ref = "warn"
133+
semicolon_if_nothing_returned = "warn"
134+
tests_outside_test_module = "warn"
135+
transmute_ptr_to_ptr = "warn"
136+
unused_peekable = "warn"
137+
unused_rounding = "warn"
138+
verbose_bit_mask = "warn"
139+
zero_sized_map_values = "warn"
140+
# Correctness/Safety
141+
case_sensitive_file_extension_comparisons = "warn"
142+
cfg_not_test = "deny"
143+
collection_is_never_read = "warn"
144+
create_dir = "warn"
145+
dbg_macro = "warn"
146+
debug_assert_with_mut_call = "deny"
147+
expl_impl_clone_on_copy = "deny"
148+
filetype_is_file = "warn"
149+
future_not_send = "warn"
150+
ignore_without_reason = "warn"
151+
infinite_loop = "warn"
152+
large_futures = "warn"
153+
large_stack_arrays = "warn"
154+
large_stack_frames = "warn"
155+
manual_midpoint = "warn"
156+
maybe_infinite_iter = "warn"
157+
mem_forget = "warn"
158+
mismatching_type_param_order = "warn"
159+
mixed_read_write_in_expression = "warn"
160+
must_use_candidate = "warn"
161+
mut_mut = "warn"
162+
non_send_fields_in_send_ty = "deny"
163+
path_buf_push_overwrite = "warn"
164+
rc_mutex = "warn"
165+
read_zero_byte_vec = "warn"
166+
significant_drop_in_scrutinee = "deny"
167+
str_split_at_newline = "warn"
168+
string_slice = "warn"
169+
suspicious_operation_groupings = "warn"
170+
suspicious_xor_used_as_pow = "warn"
171+
transmute_undefined_repr = "warn"
172+
undocumented_unsafe_blocks = "warn"
173+
unnecessary_debug_formatting = "warn"
174+
unwrap_used = "warn"
175+
# Documentation
176+
doc_link_with_quotes = "warn"
177+
doc_markdown = "warn"
178+
missing_errors_doc = "warn"
179+
missing_safety_doc = "warn"
180+
# Annoyances
181+
uninlined_format_args = "allow"

Justfile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
precommit:
2+
cargo fmt
3+
cargo clippy -- -D warnings
4+
cargo clippy --features padding_api -- -D warnings
5+
cargo test --features padding_api
6+
cargo bench --no-run
7+
8+
coverage:
9+
cargo llvm-cov --features padding_api --lcov --output-path=lcov.info --ignore-filename-regex tests\.rs
10+
genhtml lcov.info --dark-mode --flat --missed --output-directory target/coverage_html

0 commit comments

Comments
 (0)