Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 39 additions & 22 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ on:
- 'Cargo.toml'
- 'Cargo.lock'
- 'rustfmt.toml'
- 'clippy.toml'
- 'rust-toolchain.toml'
- 'justfile'
- 'src/**'
- 'tests/**'
- 'benches/**'
Expand All @@ -17,6 +20,9 @@ on:
- 'Cargo.toml'
- 'Cargo.lock'
- 'rustfmt.toml'
- 'clippy.toml'
- 'rust-toolchain.toml'
- 'justfile'
- 'src/**'
- 'tests/**'
- 'benches/**'
Expand All @@ -41,15 +47,19 @@ jobs:
steps:
- uses: actions/checkout@v7.0.1

- name: Install Rust
run: rustup toolchain install stable --profile minimal --component rustfmt && rustup default stable
# Installs the channel pinned in rust-toolchain.toml, and caches
# ~/.cargo/registry and target/debug.
- name: Install toolchain
uses: moonrepo/setup-rust@abb2d32350334249b178c401e5ec5836e0cd88d3 # v1.3.0
with:
components: rustfmt
bins: just@1.58.0
cache-base: main
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Check formatting
run: cargo fmt --check

# The wasm guest is its own workspace, so the root `cargo fmt` skips it.
- name: Check formatting of the wasm guest
run: cargo fmt --check --manifest-path tests/wasm/ts/Cargo.toml
run: just fmt-check

clippy:
name: Clippy
Expand All @@ -59,17 +69,19 @@ jobs:
steps:
- uses: actions/checkout@v7.0.1

- name: Install Rust
run: rustup toolchain install stable --profile minimal --component clippy && rustup default stable

- uses: Swatinem/rust-cache@v2.9.2
# Installs the channel pinned in rust-toolchain.toml, and caches
# ~/.cargo/registry and target/debug.
- name: Install toolchain
uses: moonrepo/setup-rust@abb2d32350334249b178c401e5ec5836e0cd88d3 # v1.3.0
with:
components: clippy
bins: just@1.58.0
cache-base: main
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Clippy (all features)
run: cargo clippy --locked --all-targets --all-features -- -D warnings

# The library on its own, as users with `default-features = false` build it.
- name: Clippy (no default features)
run: cargo clippy --locked --all-targets --no-default-features -- -D warnings
- name: Clippy
run: just lint

test:
name: Test
Expand All @@ -79,11 +91,16 @@ jobs:
steps:
- uses: actions/checkout@v7.0.1

# tests/wasm.rs builds the guest in tests/wasm/ts for wasm32-wasip2.
- name: Install Rust
run: rustup toolchain install stable --profile minimal --target wasm32-wasip2 && rustup default stable

- uses: Swatinem/rust-cache@v2.9.2
# Installs the channel pinned in rust-toolchain.toml, and caches
# ~/.cargo/registry and target/debug. tests/wasm.rs builds the guest in
# tests/wasm/ts for wasm32-wasip2.
- name: Install toolchain
uses: moonrepo/setup-rust@abb2d32350334249b178c401e5ec5836e0cd88d3 # v1.3.0
with:
targets: wasm32-wasip2
cache-base: main
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Test
run: cargo test --locked --all-features
81 changes: 81 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,84 @@ required-features = ["cli"]
[[test]]
name = "wasm"
required-features = ["cli", "wasm"]


[lints.clippy]
# https://rust-lang.github.io/rust-clippy/rust-1.88.0/index.html
allow_attributes = "deny"
assigning_clones = "warn"
cfg_not_test = "warn"
checked_conversions = "warn"
cloned_instead_of_copied = "warn"
copy_iterator = "warn"
dbg_macro = "warn"
doc_link_with_quotes = "warn"
empty_drop = "warn"
empty_enum_variants_with_brackets = "warn"
empty_enums = "warn"
expl_impl_clone_on_copy = "warn"
explicit_into_iter_loop = "warn"
filter_map_next = "warn"
flat_map_option = "warn"
float_cmp_const = "warn"
fn_params_excessive_bools = "warn"
get_unwrap = "warn"
implicit_clone = "warn"
implicit_hasher = "warn"
index_refutable_slice = "warn"
inefficient_to_string = "warn"
infinite_loop = "warn"
invalid_upcast_comparisons = "warn"
iter_filter_is_ok = "warn"
iter_not_returning_iterator = "warn"
large_stack_arrays = "warn"
large_types_passed_by_value = "warn"
lossy_float_literal = "warn"
macro_use_imports = "warn"
manual_is_variant_and = "warn"
manual_ok_or = "warn"
manual_string_new = "warn"
map_flatten = "warn"
map_unwrap_or = "warn"
mem_forget = "warn"
mismatching_type_param_order = "warn"
mut_mut = "warn"
naive_bytecount = "warn"
needless_bitwise_bool = "warn"
needless_continue = "warn"
needless_for_each = "warn"
no_effect_underscore_binding = "warn"
option_as_ref_cloned = "warn"
rc_buffer = "warn"
rc_mutex = "warn"
ref_binding_to_reference = "warn"
ref_option_ref = "warn"
rest_pat_in_fully_bound_structs = "warn"
single_char_pattern = "warn"
stable_sort_primitive = "warn"
str_split_at_newline = "warn"
string_lit_chars_any = "warn"
unnecessary_box_returns = "warn"
unnecessary_join = "warn"
unnested_or_patterns = "warn"
unreadable_literal = "warn"
verbose_bit_mask = "warn"
verbose_file_reads = "warn"
zero_sized_map_values = "warn"

[lints.rust]
# https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html
ambiguous_negative_literals = "warn"
dead_code = "warn"
explicit_outlives_requirements = "warn"
# that's for salsa
impl_trait_overcaptures = "warn"
impl_trait_redundant_captures = "allow"
missing_unsafe_on_extern = "warn"
redundant_lifetimes = "warn"
trivial_numeric_casts = "warn"
unit_bindings = "warn"
unsafe_attr_outside_unsafe = "warn"
unused_import_braces = "warn"
unused_lifetimes = "warn"
unused_macro_rules = "warn"
1 change: 1 addition & 0 deletions clippy.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
allow-dbg-in-tests = true
26 changes: 26 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Project commands. Run `just --list` to see them all. CI runs these same
# recipes, so a recipe that passes here passes there.

alias f := fmt
alias l := lint

# The wasm guest is its own workspace, so the root `cargo fmt` skips it and it
# gets its own run.

# Format the code, including the wasm guest
fmt:
cargo fmt
cargo fmt --manifest-path tests/wasm/ts/Cargo.toml

# Check formatting without changing files, as CI does
fmt-check:
cargo fmt --check
cargo fmt --check --manifest-path tests/wasm/ts/Cargo.toml

# The second run checks the library alone, as users with
# `default-features = false` build it.

# Run clippy with all features, then with no default features
lint:
cargo clippy --locked --all-targets --all-features -- -D warnings
cargo clippy --locked --all-targets --no-default-features -- -D warnings
6 changes: 6 additions & 0 deletions rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[toolchain]
# The default profile includes rustc, rust-std, cargo, rust-docs, rustfmt and clippy.
# https://rust-lang.github.io/rustup/concepts/profiles.html
profile = "default"
channel = "1.99.0"
targets = ["wasm32-unknown-unknown"]
2 changes: 1 addition & 1 deletion src/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ mod tests {

#[test]
fn integers_beyond_2_to_the_53_lose_precision() {
assert_eq!(read("9007199254740993"), Json::Number(9007199254740992.0));
assert_eq!(read("9007199254740993"), Json::Number(9_007_199_254_740_992.0));
}

#[test]
Expand Down
21 changes: 6 additions & 15 deletions src/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1003,12 +1003,7 @@ impl<'d> Builder<'d> {
/// Returns the union of `members`, which must be different, with
/// `discriminator`, which is `exclusive` if a value is at most one of
/// them.
fn push_union(
&mut self,
members: &[TypeId],
discriminator: Option<Box<DiscriminatorData>>,
exclusive: bool,
) -> TypeId {
fn push_union(&mut self, members: &[TypeId], discriminator: Option<DiscriminatorData>, exclusive: bool) -> TypeId {
let members = self.members.extend(members.iter().copied());
self.push(TypeData::Union(UnionData {
members,
Expand Down Expand Up @@ -1752,7 +1747,7 @@ impl<'d> Builder<'d> {
fn union_of(
&mut self,
members: &[TypeId],
discriminator: Option<Box<DiscriminatorData>>,
discriminator: Option<DiscriminatorData>,
mut exclusive: bool,
) -> TypeId {
let mut out = Vec::with_capacity(members.len());
Expand Down Expand Up @@ -1821,11 +1816,7 @@ impl<'d> Builder<'d> {

/// Returns the discriminator of a union of `members`, each with its
/// schema.
fn discriminator(
&mut self,
discriminator: &'d Discriminator,
members: &[(Schema, TypeId)],
) -> Box<DiscriminatorData> {
fn discriminator(&mut self, discriminator: &'d Discriminator, members: &[(Schema, TypeId)]) -> DiscriminatorData {
let doc = self.doc;
let wire_name = doc.str(discriminator.property_name);
let mut name = Name::new(wire_name);
Expand Down Expand Up @@ -1875,12 +1866,12 @@ impl<'d> Builder<'d> {
}
}
let wire_name = self.strings.push(wire_name);
Box::new(DiscriminatorData {
DiscriminatorData {
wire_name,
name,
cases,
default,
})
}
}

/// Returns the type a discriminator's mapping names: a `$ref`, or the
Expand Down Expand Up @@ -1956,7 +1947,7 @@ impl<'d> Builder<'d> {
};
let object = doc.get(object);
let has_ref = !object.reference.is_empty();
if !object.description.is_empty() && !(has_ref && self.v30) {
if !(object.description.is_empty() || has_ref && self.v30) {
return doc.str(object.description);
}
if has_ref {
Expand Down
2 changes: 1 addition & 1 deletion src/link/openapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1766,7 +1766,7 @@ impl<'de> Deserialize<'de> for Count {

fn visit_f64<E: de::Error>(self, v: f64) -> Result<Count, E> {
// 2^64 is the first float that does not fit in a `u64`.
if v >= 0.0 && v.fract() == 0.0 && v < 18_446_744_073_709_551_616.0 {
if v >= 0.0 && v.fract() == 0.0 && v < 18_446_744_073_709_552_000.0 {
Ok(Count(v as u64))
} else {
Err(E::invalid_value(de::Unexpected::Float(v), &self))
Expand Down
2 changes: 1 addition & 1 deletion src/plugin/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ impl wit::Host for State {
TypeData::Union(union) => wit::TypeInfo::Union(wit::UnionInfo {
members: forge.members.get(union.members).iter().map(|id| id.0).collect(),
exclusive: union.exclusive,
discriminator: union.discriminator.as_deref().map(|data| wit::DiscriminatorInfo {
discriminator: union.discriminator.as_ref().map(|data| wit::DiscriminatorInfo {
wire_name: s(data.wire_name),
name: words(&data.name),
cases: data.cases.iter().map(|&(value, id)| (s(value), id.0)).collect(),
Expand Down
4 changes: 2 additions & 2 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -603,8 +603,8 @@ pub(crate) struct UnionData {
pub(crate) members: Span<TypeId>,
/// Whether a value is at most one of the members.
pub(crate) exclusive: bool,
/// Boxed, since most unions have none, to keep `TypeData` small.
pub(crate) discriminator: Option<Box<DiscriminatorData>>,
/// Most unions have none.
pub(crate) discriminator: Option<DiscriminatorData>,
}

pub(crate) struct DiscriminatorData {
Expand Down
2 changes: 1 addition & 1 deletion tests/parse/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pub fn models(forge: &Forge) -> Vec<&str> {
.chain(forge.groups().flat_map(|group| group.models()))
.map(|model| model.schema_name())
.collect();
names.sort();
names.sort_unstable();
names
}

Expand Down
2 changes: 1 addition & 1 deletion tests/parse/types/unions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ fn members_with_only_required_are_dropped() {
));

let mut names = field_names(object(response_type(&forge, "a.get")));
names.sort();
names.sort_unstable();
assert_eq!(names, ["appeals", "type"]);
}

Expand Down
Loading