Skip to content

Commit 88f5bf0

Browse files
authored
Merge pull request #58 from ijackson/table
Fix handling of inline tables
2 parents e2c5dbe + 1bcfd88 commit 88f5bf0

File tree

3 files changed

+59
-25
lines changed

3 files changed

+59
-25
lines changed

.github/workflows/rust.yml

+9
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,12 @@ jobs:
4444
- uses: Swatinem/rust-cache@v2
4545
- name: Check formatting
4646
run: cargo fmt --all -- --check
47+
clippy:
48+
name: cargo clippy (forbidden methods)
49+
runs-on: ubuntu-latest
50+
steps:
51+
- uses: actions/checkout@v2
52+
- uses: dtolnay/rust-toolchain@stable
53+
# We just use clippy to spot forbidden methods.
54+
# We disable the default lint set which has much questionable output.
55+
- run: cargo clippy --all -- -A clippy::all -D clippy::disallowed_methods

clippy.toml

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
disallowed-methods = [
2+
# Avoid a repeat of https://github.com/bkchr/proc-macro-crate/issues/57
3+
{ path = "toml_edit::Item::as_table", reason = "Use .as_table_like instead!" },
4+
{ path = "toml_edit::Item::is_table", reason = "Use .is_table_like instead!" },
5+
]

src/lib.rs

+45-25
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ use std::{
9494
time::SystemTime,
9595
};
9696

97-
use toml_edit::{DocumentMut, Item, Table, TomlError};
97+
use toml_edit::{DocumentMut, Item, TableLike, TomlError};
9898

9999
/// Error type used by this crate.
100100
pub enum Error {
@@ -308,6 +308,7 @@ fn extract_workspace_dependencies(
308308
) -> Result<BTreeMap<String, String>, Error> {
309309
Ok(workspace_dep_tables(&workspace_toml)
310310
.into_iter()
311+
.map(|t| t.iter())
311312
.flatten()
312313
.map(move |(dep_name, dep_value)| {
313314
let pkg_name = dep_value.get("package").and_then(|i| i.as_str()).unwrap_or(dep_name);
@@ -318,10 +319,10 @@ fn extract_workspace_dependencies(
318319
}
319320

320321
/// Return an iterator over all `[workspace.dependencies]`
321-
fn workspace_dep_tables(cargo_toml: &DocumentMut) -> Option<&Table> {
322+
fn workspace_dep_tables(cargo_toml: &DocumentMut) -> Option<&dyn TableLike> {
322323
cargo_toml
323324
.get("workspace")
324-
.and_then(|w| w.as_table()?.get("dependencies")?.as_table())
325+
.and_then(|w| w.as_table_like()?.get("dependencies")?.as_table_like())
325326
}
326327

327328
/// Make sure that the given crate name is a valid rust identifier.
@@ -354,27 +355,29 @@ fn extract_crate_names(
354355
(name.to_string(), cr)
355356
});
356357

357-
let dep_tables = dep_tables(cargo_toml).chain(target_dep_tables(cargo_toml));
358-
let dep_pkgs = dep_tables.flatten().filter_map(move |(dep_name, dep_value)| {
359-
let pkg_name = dep_value.get("package").and_then(|i| i.as_str()).unwrap_or(dep_name);
358+
let dep_tables = dep_tables(cargo_toml.as_table()).chain(target_dep_tables(cargo_toml));
359+
let dep_pkgs =
360+
dep_tables.map(|t| t.iter()).flatten().filter_map(move |(dep_name, dep_value)| {
361+
let pkg_name = dep_value.get("package").and_then(|i| i.as_str()).unwrap_or(dep_name);
360362

361-
// We already handle this via `root_pkg` above.
362-
if package_name.as_ref().map_or(false, |n| *n == pkg_name) {
363-
return None
364-
}
363+
// We already handle this via `root_pkg` above.
364+
if package_name.as_ref().map_or(false, |n| *n == pkg_name) {
365+
return None
366+
}
365367

366-
// Check if this is a workspace dependency.
367-
let workspace = dep_value.get("workspace").and_then(|w| w.as_bool()).unwrap_or_default();
368+
// Check if this is a workspace dependency.
369+
let workspace =
370+
dep_value.get("workspace").and_then(|w| w.as_bool()).unwrap_or_default();
368371

369-
let pkg_name = workspace
370-
.then(|| workspace_dependencies.get(pkg_name).map(|p| p.as_ref()))
371-
.flatten()
372-
.unwrap_or(pkg_name);
372+
let pkg_name = workspace
373+
.then(|| workspace_dependencies.get(pkg_name).map(|p| p.as_ref()))
374+
.flatten()
375+
.unwrap_or(pkg_name);
373376

374-
let cr = FoundCrate::Name(sanitize_crate_name(dep_name));
377+
let cr = FoundCrate::Name(sanitize_crate_name(dep_name));
375378

376-
Some((pkg_name.to_owned(), cr))
377-
});
379+
Some((pkg_name.to_owned(), cr))
380+
});
378381

379382
Ok(root_pkg.into_iter().chain(dep_pkgs).collect())
380383
}
@@ -383,18 +386,25 @@ fn extract_package_name(cargo_toml: &DocumentMut) -> Option<&str> {
383386
cargo_toml.get("package")?.get("name")?.as_str()
384387
}
385388

386-
fn target_dep_tables(cargo_toml: &DocumentMut) -> impl Iterator<Item = &Table> {
387-
cargo_toml.get("target").into_iter().filter_map(Item::as_table).flat_map(|t| {
388-
t.iter().map(|(_, value)| value).filter_map(Item::as_table).flat_map(dep_tables)
389-
})
389+
fn target_dep_tables(cargo_toml: &DocumentMut) -> impl Iterator<Item = &dyn TableLike> {
390+
cargo_toml
391+
.get("target")
392+
.into_iter()
393+
.filter_map(Item::as_table_like)
394+
.flat_map(|t| {
395+
t.iter()
396+
.map(|(_, value)| value)
397+
.filter_map(Item::as_table_like)
398+
.flat_map(dep_tables)
399+
})
390400
}
391401

392-
fn dep_tables(table: &Table) -> impl Iterator<Item = &Table> {
402+
fn dep_tables(table: &dyn TableLike) -> impl Iterator<Item = &dyn TableLike> {
393403
table
394404
.get("dependencies")
395405
.into_iter()
396406
.chain(table.get("dev-dependencies"))
397-
.filter_map(Item::as_table)
407+
.filter_map(Item::as_table_like)
398408
}
399409

400410
#[cfg(test)]
@@ -438,6 +448,16 @@ mod tests {
438448
Ok(Some(FoundCrate::Name(name))) if name == "my_crate"
439449
}
440450

451+
// forbidding toml_edit::Item::as_table ought to mean this is OK, but let's have a test too
452+
create_test! {
453+
deps_with_crate_inline_table,
454+
r#"
455+
dependencies = { my_crate = "0.1" }
456+
"#,
457+
"",
458+
Ok(Some(FoundCrate::Name(name))) if name == "my_crate"
459+
}
460+
441461
create_test! {
442462
dev_deps_with_crate,
443463
r#"

0 commit comments

Comments
 (0)