Could not find in the crate root

Hello, I am writing an HTML parser and I am facing an issue finding a module with use statement.

I have an issue in module resolution :

error[E0432]: unresolved import `crate::tag_path`
 --> src\selectors\tag_name_html_selector.rs:8:12
  |
8 | use crate::tag_path::TagPathItem;
  |            ^^^^^^^^ could not find `tag_path` in the crate root

The "import" statement are bellow in the file src\selectors\tag_name_html_selector.rs

use crate::elements::start_element::Tag;
use crate::selectors::format_css_request;
use crate::tag_iterator::{Elements, TagIterator};
use crate::selectors::HtmlSelectorCounter;
use crate::selectors::HtmlSelectorFindFirst;
use crate::tag_path::TagPathItem;

The src file tree

css_selector_macro.rs
elements/
  ...
lib.rs
main.rs
selectors/
  matcher_html_selector.rs
  mod.rs
  tag_name_html_selector.rs
selector_predicates.rs
tag_iterator.rs
tag_path.rs

Here are the "use" and "mod" statements :

//...
lib.rs:mod selector_predicates;
lib.rs:mod selectors;
lib.rs:mod tag_iterator;
lib.rs:mod tag_path;
lib.rs:mod elements;
lib.rs:mod css_selector_macro;
lib.rs:use tag_path::TagPathItem;
lib.rs:use elements::start_element::extract_tag_name;
lib.rs:use elements::start_element::Tag;
lib.rs:use selectors::tag_name_html_selector::TagNameHtmlSelector;
lib.rs:use selectors::HtmlSelectorCounter;
main.rs:mod elements;
main.rs:mod selectors;
main.rs:mod tag_iterator;
main.rs:use crate::selectors::tag_name_html_selector::TagNameHtmlSelector;
main.rs:use crate::selectors::HtmlSelectorCounter;
main.rs:use std::fs;
main.rs:use std::time::Instant;
selectors/matcher_html_selector.rs:use crate::elements::start_element::Tag;
selectors/matcher_html_selector.rs:use crate::selectors::HtmlSelectorCounter;
selectors/matcher_html_selector.rs:use crate::selectors::HtmlSelectorFindFirst;
selectors/matcher_html_selector.rs:use crate::tag_iterator::Elements;
selectors/matcher_html_selector.rs:use crate::tag_iterator::TagIterator;
selectors/tag_name_html_selector.rs:use crate::elements::start_element::Tag;
selectors/tag_name_html_selector.rs:use crate::selectors::format_css_request;
selectors/tag_name_html_selector.rs:use crate::tag_iterator::{Elements, TagIterator};
selectors/tag_name_html_selector.rs:use crate::selectors::HtmlSelectorCounter;
selectors/tag_name_html_selector.rs:use crate::selectors::HtmlSelectorFindFirst;
selectors/tag_name_html_selector.rs:use crate::tag_path::TagPathItem;
selector_predicates.rs:use crate::elements::start_element::Tag;
tag_path.rs:use crate::elements::start_element::Tag;

Bonus questions : It seems I cannot avoid using mod.rs files though I am running edition 2018.

[package]
name = "stream_html_selector"
version = "0.1.0"
authors = ["xxx xxxx <xxxx@gmail.com>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

Thank for your help.

main.rs imports lib.rs under the actual name of the crate (stream_html_selector), not as the crate keyword.

You should avoid defining redundant modules main.rs (don't put mod there, use stuff via lib.rs's public interface). Otherwise you end up with the same code compiled twice, and potentially two different module structures, two different versions of every structure.

3 Likes

When you mention a file with mod twice, that duplicates everything in the module. The instance of selectors that has lib.rs as its root works fine, but the instance of selectors that has main.rs as its root is broken because there's no tag_path module with main.rs as its root.

Remove the extra mod statements from main.rs and import the ones in lib.rs.

1 Like

Oh thank you ! If I understand well main.rs auto import lib.rs.
So no mod ..... ; in the main.rs file.
Am I right ?

main.rs and lib.rs are different crates, two different compilation unit.

lib.rs defines a library crate, which you can use in your binary crate defined by main.rs.

If in your lib.rs you declare a module called foo which maps to a foo.rs file it will be compiled as part of that compilation unit, the library. If in your main.rs you declare a module called foo which maps to that same foo.rs file it will be compiled as part of that compilation unit, the binary. And the file foo.rs will have been compiled twice in two different contexts.

1 Like

Thank you for your advises. I fixed this out by using methods exposed in the lib.rs in the main.rsfile.

main.rs:

use m_crate_name::count;    // where  "count" is a public method in the lib.rs file.

Everything compile well.

An other questions : why I cannot remove mod.rs files ?

You can replace mod.rs files. There's inline mod syntax mod name { put code here } that gets its code from the code block instead of a file on disk.

If the file name is bothering you, then there's also an alternative path you can use. Instead of src/selectors/mod.rs you can use src/selectors.rs.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.