codesort/
loc.rs

1use {
2    crate::*,
3    std::{
4        cmp::Ordering,
5        fmt,
6    },
7};
8
9/// A Line of Code, analyzed.
10///
11/// While public, this is implementation dependant and may change
12/// on patch versions.
13#[derive(Debug, Clone)]
14#[non_exhaustive]
15pub struct Loc {
16    /// The whole content of the line, including the ending newline
17    pub content: String,
18    /// The key used for sorting, may be empty
19    pub sort_key: String,
20    /// number of bytes of leading spaces
21    pub indent: usize,
22    /// The syntactic depth considered on the whole file, at start of line
23    pub start_depth: usize,
24    /// The syntactic depth considered on the whole file, at end of line
25    pub end_depth: usize,
26    /// Whether this line starts a java annotation, a rust attribute, etc.
27    pub is_annotation: bool,
28    pub can_complete: bool,
29    /// wishes needed after this loc
30    pub wishes: Vec<Wish>,
31    /// gifts not required by this loc
32    pub gifts: Vec<Gift>,
33    /// Before the first char, is the line normal (not a comment or a multi line literal) ?
34    pub starts_normal: bool,
35}
36
37impl Loc {
38    /// Either the depth at start, or the depth at end, whichever is smaller
39    pub fn min_depth(&self) -> usize {
40        self.start_depth.min(self.end_depth)
41    }
42    /// Whether the deindented content starts with the given string
43    pub fn starts_with(
44        &self,
45        s: &str,
46    ) -> bool {
47        self.content[self.indent..].starts_with(s)
48    }
49    /// the last character which is not a whitespace or part of a comment
50    pub fn last_significant_char(&self) -> Option<char> {
51        self.sort_key.chars().rev().find(|c| !c.is_whitespace())
52    }
53    pub fn is_blank(&self) -> bool {
54        !self.content[self.indent..]
55            .chars()
56            .any(|c| !c.is_whitespace())
57    }
58    pub fn is_sortable(&self) -> bool {
59        !self.is_annotation && !self.sort_key.is_empty()
60    }
61}
62
63impl PartialEq for Loc {
64    fn eq(
65        &self,
66        other: &Self,
67    ) -> bool {
68        self.sort_key == other.sort_key
69    }
70}
71impl Eq for Loc {}
72impl Ord for Loc {
73    fn cmp(
74        &self,
75        other: &Self,
76    ) -> Ordering {
77        self.sort_key.cmp(&other.sort_key)
78    }
79}
80impl PartialOrd for Loc {
81    fn partial_cmp(
82        &self,
83        other: &Self,
84    ) -> Option<Ordering> {
85        Some(self.cmp(other))
86    }
87}
88
89impl fmt::Display for Loc {
90    fn fmt(
91        &self,
92        f: &mut fmt::Formatter<'_>,
93    ) -> fmt::Result {
94        write!(f, "{}", &self.content)
95    }
96}