Skip to main content

frs/cmds/rsl/rules/
common.rs

1//! Shared components for frs rsl rules.
2
3use std::path::Path;
4use std::path::PathBuf;
5
6pub use fn_call_analysis::CallDetails;
7pub(super) use fn_call_analysis::FnCallFinding;
8pub(super) use fn_call_analysis::FnCallKind;
9pub(super) use fn_call_analysis::find_fn_calls;
10pub(super) use import_resolution::has_name_clash_parts;
11pub(super) use module_idx::ModuleIdx;
12pub(super) use module_idx::module_idx;
13pub(super) use path_resolution::associated_receiver_parts;
14pub(super) use path_resolution::is_import_style_path;
15pub(super) use path_resolution::path_parts;
16use proc_macro2::Span;
17
18mod fn_call_analysis;
19mod fn_path_resolution;
20mod import_resolution;
21mod module_idx;
22mod path_resolution;
23mod scope_bindings;
24
25#[derive(Debug)]
26#[cfg_attr(test, derive(Eq, PartialEq))]
27pub struct Location {
28    pub file: PathBuf,
29    pub line: usize,
30    pub column: usize,
31}
32
33impl Location {
34    pub const fn new(file: PathBuf, line: usize, column: usize) -> Self {
35        Self { file, line, column }
36    }
37
38    pub fn from_span(path: &Path, span: Span) -> Self {
39        let start = span.start();
40        Self::new(path.to_path_buf(), start.line, start.column.saturating_add(1))
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use std::path::Path;
47    use std::path::PathBuf;
48
49    use syn::spanned::Spanned;
50
51    use super::Location;
52
53    #[test]
54    fn test_location_from_span_when_span_starts_at_file_start_uses_one_based_column() {
55        let item: syn::ItemFn = syn::parse_str("fn main() {}").unwrap();
56
57        let actual = Location::from_span(Path::new("test.rs"), item.span());
58
59        assert_eq!(
60            actual,
61            Location {
62                file: PathBuf::from("test.rs"),
63                line: 1,
64                column: 1,
65            }
66        );
67    }
68}