mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-01-03 05:10:12 +02:00
printer: clean-up
Like a previous commit did for the grep-cli crate, this does some polishing to the grep-printer crate. We aren't able to achieve as much as we did with grep-cli, but we at least eliminate all rust-analyzer lints and group imports in the way I've been doing recently. Next we'll start doing some more invasive changes.
This commit is contained in:
parent
25a7145c79
commit
09905560ff
5
Cargo.lock
generated
5
Cargo.lock
generated
@ -19,9 +19,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.20.0"
|
||||
version = "0.21.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5"
|
||||
checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
@ -220,7 +220,6 @@ dependencies = [
|
||||
"grep-matcher",
|
||||
"grep-regex",
|
||||
"grep-searcher",
|
||||
"lazy_static",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"termcolor",
|
||||
|
@ -12,22 +12,33 @@ repository = "https://github.com/BurntSushi/ripgrep/tree/master/crates/printer"
|
||||
readme = "README.md"
|
||||
keywords = ["grep", "pattern", "print", "printer", "sink"]
|
||||
license = "Unlicense OR MIT"
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
|
||||
[features]
|
||||
default = ["serde1"]
|
||||
serde1 = ["base64", "serde", "serde_json"]
|
||||
default = ["serde"]
|
||||
serde = ["dep:base64", "dep:serde", "dep:serde_json"]
|
||||
|
||||
[dependencies]
|
||||
base64 = { version = "0.20.0", optional = true }
|
||||
bstr = "1.6.0"
|
||||
base64 = { version = "0.21.4", optional = true }
|
||||
bstr = "1.6.2"
|
||||
gethostname = "0.4.3"
|
||||
grep-matcher = { version = "0.1.6", path = "../matcher" }
|
||||
grep-searcher = { version = "0.1.11", path = "../searcher" }
|
||||
lazy_static = "1.1.0"
|
||||
termcolor = "1.0.4"
|
||||
serde = { version = "1.0.77", optional = true, features = ["derive"] }
|
||||
serde_json = { version = "1.0.27", optional = true }
|
||||
termcolor = "1.3.0"
|
||||
serde = { version = "1.0.188", optional = true, features = ["derive"] }
|
||||
serde_json = { version = "1.0.107", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
grep-regex = { version = "0.1.11", path = "../regex" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
# We want to document all features.
|
||||
all-features = true
|
||||
# This opts into a nightly unstable option to show the features that need to be
|
||||
# enabled for public API items. To do that, we set 'docsrs', and when that's
|
||||
# enabled, we enable the 'doc_auto_cfg' feature.
|
||||
#
|
||||
# To test this locally, run:
|
||||
#
|
||||
# RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --all-features
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
@ -1,7 +1,3 @@
|
||||
use std::error;
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
|
||||
use termcolor::{Color, ColorSpec, ParseColorError};
|
||||
|
||||
/// Returns a default set of color specifications.
|
||||
@ -38,17 +34,7 @@ pub enum ColorError {
|
||||
InvalidFormat(String),
|
||||
}
|
||||
|
||||
impl error::Error for ColorError {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
ColorError::UnrecognizedOutType(_) => "unrecognized output type",
|
||||
ColorError::UnrecognizedSpecType(_) => "unrecognized spec type",
|
||||
ColorError::UnrecognizedColor(_, _) => "unrecognized color name",
|
||||
ColorError::UnrecognizedStyle(_) => "unrecognized style attribute",
|
||||
ColorError::InvalidFormat(_) => "invalid color spec",
|
||||
}
|
||||
}
|
||||
}
|
||||
impl std::error::Error for ColorError {}
|
||||
|
||||
impl ColorError {
|
||||
fn from_parse_error(err: ParseColorError) -> ColorError {
|
||||
@ -59,33 +45,33 @@ impl ColorError {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ColorError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
impl std::fmt::Display for ColorError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match *self {
|
||||
ColorError::UnrecognizedOutType(ref name) => write!(
|
||||
f,
|
||||
"unrecognized output type '{}'. Choose from: \
|
||||
path, line, column, match.",
|
||||
path, line, column, match.",
|
||||
name,
|
||||
),
|
||||
ColorError::UnrecognizedSpecType(ref name) => write!(
|
||||
f,
|
||||
"unrecognized spec type '{}'. Choose from: \
|
||||
fg, bg, style, none.",
|
||||
fg, bg, style, none.",
|
||||
name,
|
||||
),
|
||||
ColorError::UnrecognizedColor(_, ref msg) => write!(f, "{}", msg),
|
||||
ColorError::UnrecognizedStyle(ref name) => write!(
|
||||
f,
|
||||
"unrecognized style attribute '{}'. Choose from: \
|
||||
nobold, bold, nointense, intense, nounderline, \
|
||||
underline.",
|
||||
nobold, bold, nointense, intense, nounderline, \
|
||||
underline.",
|
||||
name,
|
||||
),
|
||||
ColorError::InvalidFormat(ref original) => write!(
|
||||
f,
|
||||
"invalid color spec format: '{}'. Valid format \
|
||||
is '(path|line|column|match):(fg|bg|style):(value)'.",
|
||||
is '(path|line|column|match):(fg|bg|style):(value)'.",
|
||||
original,
|
||||
),
|
||||
}
|
||||
@ -305,7 +291,7 @@ impl SpecValue {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for UserColorSpec {
|
||||
impl std::str::FromStr for UserColorSpec {
|
||||
type Err = ColorError;
|
||||
|
||||
fn from_str(s: &str) -> Result<UserColorSpec, ColorError> {
|
||||
@ -345,7 +331,7 @@ impl FromStr for UserColorSpec {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for OutType {
|
||||
impl std::str::FromStr for OutType {
|
||||
type Err = ColorError;
|
||||
|
||||
fn from_str(s: &str) -> Result<OutType, ColorError> {
|
||||
@ -359,7 +345,7 @@ impl FromStr for OutType {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for SpecType {
|
||||
impl std::str::FromStr for SpecType {
|
||||
type Err = ColorError;
|
||||
|
||||
fn from_str(s: &str) -> Result<SpecType, ColorError> {
|
||||
@ -373,7 +359,7 @@ impl FromStr for SpecType {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Style {
|
||||
impl std::str::FromStr for Style {
|
||||
type Err = ColorError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Style, ColorError> {
|
||||
|
@ -5,32 +5,32 @@ use termcolor::{ColorSpec, HyperlinkSpec, WriteColor};
|
||||
/// A writer that counts the number of bytes that have been successfully
|
||||
/// written.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CounterWriter<W> {
|
||||
pub(crate) struct CounterWriter<W> {
|
||||
wtr: W,
|
||||
count: u64,
|
||||
total_count: u64,
|
||||
}
|
||||
|
||||
impl<W: Write> CounterWriter<W> {
|
||||
pub fn new(wtr: W) -> CounterWriter<W> {
|
||||
CounterWriter { wtr: wtr, count: 0, total_count: 0 }
|
||||
pub(crate) fn new(wtr: W) -> CounterWriter<W> {
|
||||
CounterWriter { wtr, count: 0, total_count: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
impl<W> CounterWriter<W> {
|
||||
/// Returns the total number of bytes written since construction or the
|
||||
/// last time `reset` was called.
|
||||
pub fn count(&self) -> u64 {
|
||||
pub(crate) fn count(&self) -> u64 {
|
||||
self.count
|
||||
}
|
||||
|
||||
/// Returns the total number of bytes written since construction.
|
||||
pub fn total_count(&self) -> u64 {
|
||||
pub(crate) fn total_count(&self) -> u64 {
|
||||
self.total_count + self.count
|
||||
}
|
||||
|
||||
/// Resets the number of bytes written to `0`.
|
||||
pub fn reset_count(&mut self) {
|
||||
pub(crate) fn reset_count(&mut self) {
|
||||
self.total_count += self.count;
|
||||
self.count = 0;
|
||||
}
|
||||
@ -40,21 +40,21 @@ impl<W> CounterWriter<W> {
|
||||
/// After this call, the total count of bytes written to the underlying
|
||||
/// writer is erased and reset.
|
||||
#[allow(dead_code)]
|
||||
pub fn clear(&mut self) {
|
||||
pub(crate) fn clear(&mut self) {
|
||||
self.count = 0;
|
||||
self.total_count = 0;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_ref(&self) -> &W {
|
||||
pub(crate) fn get_ref(&self) -> &W {
|
||||
&self.wtr
|
||||
}
|
||||
|
||||
pub fn get_mut(&mut self) -> &mut W {
|
||||
pub(crate) fn get_mut(&mut self) -> &mut W {
|
||||
&mut self.wtr
|
||||
}
|
||||
|
||||
pub fn into_inner(self) -> W {
|
||||
pub(crate) fn into_inner(self) -> W {
|
||||
self.wtr
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,14 @@
|
||||
use std::{
|
||||
io::{self, Write},
|
||||
path::Path,
|
||||
};
|
||||
|
||||
use {
|
||||
bstr::ByteSlice,
|
||||
termcolor::{HyperlinkSpec, WriteColor},
|
||||
};
|
||||
|
||||
use crate::hyperlink_aliases::HYPERLINK_PATTERN_ALIASES;
|
||||
use bstr::ByteSlice;
|
||||
use std::error::Error;
|
||||
use std::fmt::Display;
|
||||
use std::io;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
use std::str::FromStr;
|
||||
use termcolor::{HyperlinkSpec, WriteColor};
|
||||
|
||||
/// A builder for `HyperlinkPattern`.
|
||||
///
|
||||
@ -65,7 +67,8 @@ pub struct HyperlinkValues<'a> {
|
||||
|
||||
/// Represents the {file} part of a hyperlink.
|
||||
///
|
||||
/// This is the value to use as-is in the hyperlink, converted from an OS file path.
|
||||
/// This is the value to use as-is in the hyperlink, converted from an OS file
|
||||
/// path.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct HyperlinkPath(Vec<u8>);
|
||||
|
||||
@ -231,7 +234,7 @@ impl HyperlinkPattern {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for HyperlinkPattern {
|
||||
impl std::str::FromStr for HyperlinkPattern {
|
||||
type Err = HyperlinkPatternError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
@ -308,24 +311,31 @@ impl ToString for Part {
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for HyperlinkPatternError {
|
||||
impl std::fmt::Display for HyperlinkPatternError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
HyperlinkPatternError::InvalidSyntax => {
|
||||
write!(f, "invalid hyperlink pattern syntax")
|
||||
}
|
||||
HyperlinkPatternError::NoFilePlaceholder => {
|
||||
write!(f, "the {{file}} placeholder is required in hyperlink patterns")
|
||||
write!(
|
||||
f,
|
||||
"the {{file}} placeholder is required in hyperlink \
|
||||
patterns",
|
||||
)
|
||||
}
|
||||
HyperlinkPatternError::NoLinePlaceholder => {
|
||||
write!(f, "the hyperlink pattern contains a {{column}} placeholder, \
|
||||
but no {{line}} placeholder is present")
|
||||
write!(
|
||||
f,
|
||||
"the hyperlink pattern contains a {{column}} placeholder, \
|
||||
but no {{line}} placeholder is present",
|
||||
)
|
||||
}
|
||||
HyperlinkPatternError::InvalidPlaceholder(name) => {
|
||||
write!(
|
||||
f,
|
||||
"invalid hyperlink pattern placeholder: '{}', choose from: \
|
||||
file, line, column, host",
|
||||
"invalid hyperlink pattern placeholder: '{}', choose \
|
||||
from: file, line, column, host",
|
||||
name
|
||||
)
|
||||
}
|
||||
@ -339,7 +349,7 @@ impl Display for HyperlinkPatternError {
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for HyperlinkPatternError {}
|
||||
impl std::error::Error for HyperlinkPatternError {}
|
||||
|
||||
impl<'a> HyperlinkValues<'a> {
|
||||
/// Creates a new set of hyperlink values.
|
||||
@ -360,8 +370,9 @@ impl HyperlinkPath {
|
||||
/// Returns a hyperlink path from an OS path.
|
||||
#[cfg(unix)]
|
||||
pub fn from_path(path: &Path) -> Option<Self> {
|
||||
// On Unix, this function returns the absolute file path without the leading slash,
|
||||
// as it makes for more natural hyperlink patterns, for instance:
|
||||
// On Unix, this function returns the absolute file path without the
|
||||
// leading slash, as it makes for more natural hyperlink patterns, for
|
||||
// instance:
|
||||
// file://{host}/{file} instead of file://{host}{file}
|
||||
// vscode://file/{file} instead of vscode://file{file}
|
||||
// It also allows for patterns to be multi-platform.
|
||||
@ -410,11 +421,12 @@ impl HyperlinkPath {
|
||||
// Also note that the file://C:/dir/file.txt syntax is not correct,
|
||||
// even though it often works in practice.
|
||||
//
|
||||
// In the end, this choice was confirmed by VSCode, whose pattern
|
||||
// is vscode://file/{file}:{line}:{column} and which correctly understands
|
||||
// In the end, this choice was confirmed by VSCode, whose pattern is
|
||||
// vscode://file/{file}:{line}:{column} and which correctly understands
|
||||
// the following URL format for network drives:
|
||||
// vscode://file//server/dir/file.txt:1:1
|
||||
// It doesn't parse any other number of slashes in "file//server" as a network path.
|
||||
// It doesn't parse any other number of slashes in "file//server" as a
|
||||
// network path.
|
||||
|
||||
const WIN32_NAMESPACE_PREFIX: &[u8] = br"\\?\";
|
||||
const UNC_PREFIX: &[u8] = br"UNC\";
|
||||
@ -438,14 +450,15 @@ impl HyperlinkPath {
|
||||
/// Percent-encodes a path.
|
||||
///
|
||||
/// The alphanumeric ASCII characters and "-", ".", "_", "~" are unreserved
|
||||
/// as per section 2.3 of RFC 3986 (Uniform Resource Identifier (URI): Generic Syntax),
|
||||
/// and are not encoded. The other ASCII characters except "/" and ":" are percent-encoded,
|
||||
/// and "\" is replaced by "/" on Windows.
|
||||
/// as per section 2.3 of RFC 3986 (Uniform Resource Identifier (URI):
|
||||
/// Generic Syntax), and are not encoded. The other ASCII characters except
|
||||
/// "/" and ":" are percent-encoded, and "\" is replaced by "/" on Windows.
|
||||
///
|
||||
/// Section 4 of RFC 8089 (The "file" URI Scheme) does not mandate precise encoding
|
||||
/// requirements for non-ASCII characters, and this implementation leaves them unencoded.
|
||||
/// On Windows, the UrlCreateFromPathW function does not encode non-ASCII characters.
|
||||
/// Doing so with UTF-8 encoded paths creates invalid file:// URLs on that platform.
|
||||
/// Section 4 of RFC 8089 (The "file" URI Scheme) does not mandate precise
|
||||
/// encoding requirements for non-ASCII characters, and this implementation
|
||||
/// leaves them unencoded. On Windows, the UrlCreateFromPathW function does
|
||||
/// not encode non-ASCII characters. Doing so with UTF-8 encoded paths
|
||||
/// creates invalid file:// URLs on that platform.
|
||||
fn encode(input: &[u8]) -> HyperlinkPath {
|
||||
let mut result = Vec::with_capacity(input.len());
|
||||
|
||||
@ -480,7 +493,7 @@ impl HyperlinkPath {
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for HyperlinkPath {
|
||||
impl std::fmt::Display for HyperlinkPath {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
@ -490,15 +503,16 @@ impl Display for HyperlinkPath {
|
||||
}
|
||||
}
|
||||
|
||||
/// A simple abstraction over a hyperlink span written to the terminal.
|
||||
/// This helps tracking whether a hyperlink has been started, and should be ended.
|
||||
/// A simple abstraction over a hyperlink span written to the terminal. This
|
||||
/// helps tracking whether a hyperlink has been started, and should be ended.
|
||||
#[derive(Debug, Default)]
|
||||
pub struct HyperlinkSpan {
|
||||
active: bool,
|
||||
}
|
||||
|
||||
impl HyperlinkSpan {
|
||||
/// Starts a hyperlink and returns a span which tracks whether it is still in effect.
|
||||
/// Starts a hyperlink and returns a span which tracks whether it is still
|
||||
/// in effect.
|
||||
pub fn start(
|
||||
wtr: &mut impl WriteColor,
|
||||
hyperlink: &HyperlinkSpec,
|
||||
@ -528,6 +542,8 @@ impl HyperlinkSpan {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::str::FromStr;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
@ -653,7 +669,8 @@ mod tests {
|
||||
for name in names {
|
||||
assert!(
|
||||
name > previous_name,
|
||||
r#""{}" should be sorted before "{}" in `HYPERLINK_PATTERN_ALIASES`"#,
|
||||
"'{}' should be sorted before '{}' \
|
||||
in HYPERLINK_PATTERN_ALIASES",
|
||||
name,
|
||||
previous_name
|
||||
);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/// Aliases to well-known hyperlink schemes.
|
||||
///
|
||||
/// These need to be sorted by name.
|
||||
pub const HYPERLINK_PATTERN_ALIASES: &[(&str, &str)] = &[
|
||||
pub(crate) const HYPERLINK_PATTERN_ALIASES: &[(&str, &str)] = &[
|
||||
#[cfg(unix)]
|
||||
("file", "file://{host}/{file}"),
|
||||
#[cfg(windows)]
|
||||
|
@ -1,17 +1,20 @@
|
||||
use std::io::{self, Write};
|
||||
use std::path::Path;
|
||||
use std::time::Instant;
|
||||
|
||||
use grep_matcher::{Match, Matcher};
|
||||
use grep_searcher::{
|
||||
Searcher, Sink, SinkContext, SinkContextKind, SinkFinish, SinkMatch,
|
||||
use std::{
|
||||
io::{self, Write},
|
||||
path::Path,
|
||||
time::Instant,
|
||||
};
|
||||
use serde_json as json;
|
||||
|
||||
use crate::counter::CounterWriter;
|
||||
use crate::jsont;
|
||||
use crate::stats::Stats;
|
||||
use crate::util::find_iter_at_in_context;
|
||||
use {
|
||||
grep_matcher::{Match, Matcher},
|
||||
grep_searcher::{
|
||||
Searcher, Sink, SinkContext, SinkContextKind, SinkFinish, SinkMatch,
|
||||
},
|
||||
serde_json as json,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
counter::CounterWriter, jsont, stats::Stats, util::find_iter_at_in_context,
|
||||
};
|
||||
|
||||
/// The configuration for the JSON printer.
|
||||
///
|
||||
@ -467,7 +470,7 @@ impl<W: io::Write> JSON<W> {
|
||||
matcher: M,
|
||||
) -> JSONSink<'static, 's, M, W> {
|
||||
JSONSink {
|
||||
matcher: matcher,
|
||||
matcher,
|
||||
json: self,
|
||||
path: None,
|
||||
start_time: Instant::now(),
|
||||
@ -493,7 +496,7 @@ impl<W: io::Write> JSON<W> {
|
||||
P: ?Sized + AsRef<Path>,
|
||||
{
|
||||
JSONSink {
|
||||
matcher: matcher,
|
||||
matcher,
|
||||
json: self,
|
||||
path: Some(path.as_ref()),
|
||||
start_time: Instant::now(),
|
||||
|
@ -6,19 +6,19 @@
|
||||
// convenient for deserialization however, so these types would become a bit
|
||||
// more complex.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::path::Path;
|
||||
use std::str;
|
||||
use std::{borrow::Cow, path::Path};
|
||||
|
||||
use base64;
|
||||
use serde::{Serialize, Serializer};
|
||||
use {
|
||||
base64,
|
||||
serde::{Serialize, Serializer},
|
||||
};
|
||||
|
||||
use crate::stats::Stats;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(tag = "type", content = "data")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Message<'a> {
|
||||
pub(crate) enum Message<'a> {
|
||||
Begin(Begin<'a>),
|
||||
End(End<'a>),
|
||||
Match(Match<'a>),
|
||||
@ -26,48 +26,48 @@ pub enum Message<'a> {
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Begin<'a> {
|
||||
pub(crate) struct Begin<'a> {
|
||||
#[serde(serialize_with = "ser_path")]
|
||||
pub path: Option<&'a Path>,
|
||||
pub(crate) path: Option<&'a Path>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct End<'a> {
|
||||
pub(crate) struct End<'a> {
|
||||
#[serde(serialize_with = "ser_path")]
|
||||
pub path: Option<&'a Path>,
|
||||
pub binary_offset: Option<u64>,
|
||||
pub stats: Stats,
|
||||
pub(crate) path: Option<&'a Path>,
|
||||
pub(crate) binary_offset: Option<u64>,
|
||||
pub(crate) stats: Stats,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Match<'a> {
|
||||
pub(crate) struct Match<'a> {
|
||||
#[serde(serialize_with = "ser_path")]
|
||||
pub path: Option<&'a Path>,
|
||||
pub(crate) path: Option<&'a Path>,
|
||||
#[serde(serialize_with = "ser_bytes")]
|
||||
pub lines: &'a [u8],
|
||||
pub line_number: Option<u64>,
|
||||
pub absolute_offset: u64,
|
||||
pub submatches: &'a [SubMatch<'a>],
|
||||
pub(crate) lines: &'a [u8],
|
||||
pub(crate) line_number: Option<u64>,
|
||||
pub(crate) absolute_offset: u64,
|
||||
pub(crate) submatches: &'a [SubMatch<'a>],
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Context<'a> {
|
||||
pub(crate) struct Context<'a> {
|
||||
#[serde(serialize_with = "ser_path")]
|
||||
pub path: Option<&'a Path>,
|
||||
pub(crate) path: Option<&'a Path>,
|
||||
#[serde(serialize_with = "ser_bytes")]
|
||||
pub lines: &'a [u8],
|
||||
pub line_number: Option<u64>,
|
||||
pub absolute_offset: u64,
|
||||
pub submatches: &'a [SubMatch<'a>],
|
||||
pub(crate) lines: &'a [u8],
|
||||
pub(crate) line_number: Option<u64>,
|
||||
pub(crate) absolute_offset: u64,
|
||||
pub(crate) submatches: &'a [SubMatch<'a>],
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct SubMatch<'a> {
|
||||
pub(crate) struct SubMatch<'a> {
|
||||
#[serde(rename = "match")]
|
||||
#[serde(serialize_with = "ser_bytes")]
|
||||
pub m: &'a [u8],
|
||||
pub start: usize,
|
||||
pub end: usize,
|
||||
pub(crate) m: &'a [u8],
|
||||
pub(crate) start: usize,
|
||||
pub(crate) end: usize,
|
||||
}
|
||||
|
||||
/// Data represents things that look like strings, but may actually not be
|
||||
@ -91,7 +91,7 @@ enum Data<'a> {
|
||||
|
||||
impl<'a> Data<'a> {
|
||||
fn from_bytes(bytes: &[u8]) -> Data<'_> {
|
||||
match str::from_utf8(bytes) {
|
||||
match std::str::from_utf8(bytes) {
|
||||
Ok(text) => Data::Text { text: Cow::Borrowed(text) },
|
||||
Err(_) => Data::Bytes { bytes },
|
||||
}
|
||||
@ -123,7 +123,8 @@ where
|
||||
T: AsRef<[u8]>,
|
||||
S: Serializer,
|
||||
{
|
||||
ser.serialize_str(&base64::encode(&bytes))
|
||||
use base64::engine::{general_purpose::STANDARD, Engine};
|
||||
ser.serialize_str(&STANDARD.encode(&bytes))
|
||||
}
|
||||
|
||||
fn ser_bytes<T, S>(bytes: T, ser: S) -> Result<S::Ok, S::Error>
|
||||
|
@ -27,11 +27,11 @@ contain matches.
|
||||
This example shows how to create a "standard" printer and execute a search.
|
||||
|
||||
```
|
||||
use std::error::Error;
|
||||
|
||||
use grep_regex::RegexMatcher;
|
||||
use grep_printer::Standard;
|
||||
use grep_searcher::Searcher;
|
||||
use {
|
||||
grep_regex::RegexMatcher,
|
||||
grep_printer::Standard,
|
||||
grep_searcher::Searcher,
|
||||
};
|
||||
|
||||
const SHERLOCK: &'static [u8] = b"\
|
||||
For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||
@ -42,41 +42,40 @@ but Doctor Watson has to have it taken out for him and dusted,
|
||||
and exhibited clearly, with a label attached.
|
||||
";
|
||||
|
||||
# fn main() { example().unwrap(); }
|
||||
fn example() -> Result<(), Box<Error>> {
|
||||
let matcher = RegexMatcher::new(r"Sherlock")?;
|
||||
let mut printer = Standard::new_no_color(vec![]);
|
||||
Searcher::new().search_slice(&matcher, SHERLOCK, printer.sink(&matcher))?;
|
||||
let matcher = RegexMatcher::new(r"Sherlock")?;
|
||||
let mut printer = Standard::new_no_color(vec![]);
|
||||
Searcher::new().search_slice(&matcher, SHERLOCK, printer.sink(&matcher))?;
|
||||
|
||||
// into_inner gives us back the underlying writer we provided to
|
||||
// new_no_color, which is wrapped in a termcolor::NoColor. Thus, a second
|
||||
// into_inner gives us back the actual buffer.
|
||||
let output = String::from_utf8(printer.into_inner().into_inner())?;
|
||||
let expected = "\
|
||||
// into_inner gives us back the underlying writer we provided to
|
||||
// new_no_color, which is wrapped in a termcolor::NoColor. Thus, a second
|
||||
// into_inner gives us back the actual buffer.
|
||||
let output = String::from_utf8(printer.into_inner().into_inner())?;
|
||||
let expected = "\
|
||||
1:For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||
3:be, to a very large extent, the result of luck. Sherlock Holmes
|
||||
";
|
||||
assert_eq!(output, expected);
|
||||
Ok(())
|
||||
}
|
||||
assert_eq!(output, expected);
|
||||
# Ok::<(), Box<dyn std::error::Error>>(())
|
||||
```
|
||||
*/
|
||||
|
||||
#![deny(missing_docs)]
|
||||
#![cfg_attr(feature = "pattern", feature(pattern))]
|
||||
|
||||
pub use crate::color::{
|
||||
default_color_specs, ColorError, ColorSpecs, UserColorSpec,
|
||||
pub use crate::{
|
||||
color::{default_color_specs, ColorError, ColorSpecs, UserColorSpec},
|
||||
hyperlink::{
|
||||
HyperlinkPath, HyperlinkPattern, HyperlinkPatternBuilder,
|
||||
HyperlinkPatternError, HyperlinkSpan, HyperlinkValues,
|
||||
},
|
||||
standard::{Standard, StandardBuilder, StandardSink},
|
||||
stats::Stats,
|
||||
summary::{Summary, SummaryBuilder, SummaryKind, SummarySink},
|
||||
util::PrinterPath,
|
||||
};
|
||||
pub use crate::hyperlink::{
|
||||
HyperlinkPath, HyperlinkPattern, HyperlinkPatternError, HyperlinkSpan,
|
||||
HyperlinkValues,
|
||||
};
|
||||
#[cfg(feature = "serde1")]
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
pub use crate::json::{JSONBuilder, JSONSink, JSON};
|
||||
pub use crate::standard::{Standard, StandardBuilder, StandardSink};
|
||||
pub use crate::stats::Stats;
|
||||
pub use crate::summary::{Summary, SummaryBuilder, SummaryKind, SummarySink};
|
||||
pub use crate::util::PrinterPath;
|
||||
|
||||
// The maximum number of bytes to execute a search to account for look-ahead.
|
||||
//
|
||||
@ -96,9 +95,9 @@ mod color;
|
||||
mod counter;
|
||||
mod hyperlink;
|
||||
mod hyperlink_aliases;
|
||||
#[cfg(feature = "serde1")]
|
||||
#[cfg(feature = "serde")]
|
||||
mod json;
|
||||
#[cfg(feature = "serde1")]
|
||||
#[cfg(feature = "serde")]
|
||||
mod jsont;
|
||||
mod standard;
|
||||
mod stats;
|
||||
|
@ -1,25 +1,31 @@
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::cmp;
|
||||
use std::io::{self, Write};
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::time::Instant;
|
||||
|
||||
use bstr::ByteSlice;
|
||||
use grep_matcher::{Match, Matcher};
|
||||
use grep_searcher::{
|
||||
LineStep, Searcher, Sink, SinkContext, SinkContextKind, SinkFinish,
|
||||
SinkMatch,
|
||||
use std::{
|
||||
cell::{Cell, RefCell},
|
||||
cmp,
|
||||
io::{self, Write},
|
||||
path::Path,
|
||||
sync::Arc,
|
||||
time::Instant,
|
||||
};
|
||||
use termcolor::{ColorSpec, NoColor, WriteColor};
|
||||
|
||||
use crate::color::ColorSpecs;
|
||||
use crate::counter::CounterWriter;
|
||||
use crate::hyperlink::{HyperlinkPattern, HyperlinkSpan};
|
||||
use crate::stats::Stats;
|
||||
use crate::util::{
|
||||
find_iter_at_in_context, trim_ascii_prefix, trim_line_terminator,
|
||||
PrinterPath, Replacer, Sunk,
|
||||
use {
|
||||
bstr::ByteSlice,
|
||||
grep_matcher::{Match, Matcher},
|
||||
grep_searcher::{
|
||||
LineStep, Searcher, Sink, SinkContext, SinkContextKind, SinkFinish,
|
||||
SinkMatch,
|
||||
},
|
||||
termcolor::{ColorSpec, NoColor, WriteColor},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
color::ColorSpecs,
|
||||
counter::CounterWriter,
|
||||
hyperlink::{HyperlinkPattern, HyperlinkSpan},
|
||||
stats::Stats,
|
||||
util::{
|
||||
find_iter_at_in_context, trim_ascii_prefix, trim_line_terminator,
|
||||
PrinterPath, Replacer, Sunk,
|
||||
},
|
||||
};
|
||||
|
||||
/// The configuration for the standard printer.
|
||||
@ -522,7 +528,7 @@ impl<W: WriteColor> Standard<W> {
|
||||
let stats = if self.config.stats { Some(Stats::new()) } else { None };
|
||||
let needs_match_granularity = self.needs_match_granularity();
|
||||
StandardSink {
|
||||
matcher: matcher,
|
||||
matcher,
|
||||
standard: self,
|
||||
replacer: Replacer::new(),
|
||||
path: None,
|
||||
@ -530,8 +536,8 @@ impl<W: WriteColor> Standard<W> {
|
||||
match_count: 0,
|
||||
after_context_remaining: 0,
|
||||
binary_byte_offset: None,
|
||||
stats: stats,
|
||||
needs_match_granularity: needs_match_granularity,
|
||||
stats,
|
||||
needs_match_granularity,
|
||||
}
|
||||
}
|
||||
|
||||
@ -558,7 +564,7 @@ impl<W: WriteColor> Standard<W> {
|
||||
);
|
||||
let needs_match_granularity = self.needs_match_granularity();
|
||||
StandardSink {
|
||||
matcher: matcher,
|
||||
matcher,
|
||||
standard: self,
|
||||
replacer: Replacer::new(),
|
||||
path: Some(ppath),
|
||||
@ -566,8 +572,8 @@ impl<W: WriteColor> Standard<W> {
|
||||
match_count: 0,
|
||||
after_context_remaining: 0,
|
||||
binary_byte_offset: None,
|
||||
stats: stats,
|
||||
needs_match_granularity: needs_match_granularity,
|
||||
stats,
|
||||
needs_match_granularity,
|
||||
}
|
||||
}
|
||||
|
||||
@ -935,8 +941,8 @@ impl<'a, M: Matcher, W: WriteColor> StandardImpl<'a, M, W> {
|
||||
sink: &'a StandardSink<'_, '_, M, W>,
|
||||
) -> StandardImpl<'a, M, W> {
|
||||
StandardImpl {
|
||||
searcher: searcher,
|
||||
sink: sink,
|
||||
searcher,
|
||||
sink,
|
||||
sunk: Sunk::empty(),
|
||||
in_color_match: Cell::new(false),
|
||||
}
|
||||
@ -954,7 +960,7 @@ impl<'a, M: Matcher, W: WriteColor> StandardImpl<'a, M, W> {
|
||||
&sink.standard.matches,
|
||||
sink.replacer.replacement(),
|
||||
);
|
||||
StandardImpl { sunk: sunk, ..StandardImpl::new(searcher, sink) }
|
||||
StandardImpl { sunk, ..StandardImpl::new(searcher, sink) }
|
||||
}
|
||||
|
||||
/// Bundle self with a searcher and return the core implementation of Sink
|
||||
@ -969,7 +975,7 @@ impl<'a, M: Matcher, W: WriteColor> StandardImpl<'a, M, W> {
|
||||
&sink.standard.matches,
|
||||
sink.replacer.replacement(),
|
||||
);
|
||||
StandardImpl { sunk: sunk, ..StandardImpl::new(searcher, sink) }
|
||||
StandardImpl { sunk, ..StandardImpl::new(searcher, sink) }
|
||||
}
|
||||
|
||||
fn sink(&self) -> io::Result<()> {
|
||||
@ -1657,9 +1663,10 @@ impl<'a, M: Matcher, W: WriteColor> PreludeWriter<'a, M, W> {
|
||||
|
||||
/// Starts the prelude with a hyperlink when applicable.
|
||||
///
|
||||
/// If a heading was written, and the hyperlink pattern is invariant on the line number,
|
||||
/// then this doesn't hyperlink each line prelude, as it wouldn't point to the line anyway.
|
||||
/// The hyperlink on the heading should be sufficient and less confusing.
|
||||
/// If a heading was written, and the hyperlink pattern is invariant on
|
||||
/// the line number, then this doesn't hyperlink each line prelude, as it
|
||||
/// wouldn't point to the line anyway. The hyperlink on the heading should
|
||||
/// be sufficient and less confusing.
|
||||
fn start(
|
||||
&mut self,
|
||||
line_number: Option<u64>,
|
||||
|
@ -1,5 +1,7 @@
|
||||
use std::ops::{Add, AddAssign};
|
||||
use std::time::Duration;
|
||||
use std::{
|
||||
ops::{Add, AddAssign},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use crate::util::NiceDuration;
|
||||
|
||||
@ -8,7 +10,7 @@ use crate::util::NiceDuration;
|
||||
/// When statistics are reported by a printer, they correspond to all searches
|
||||
/// executed with that printer.
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "serde1", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
||||
pub struct Stats {
|
||||
elapsed: NiceDuration,
|
||||
searches: u64,
|
||||
|
@ -1,18 +1,24 @@
|
||||
use std::cell::RefCell;
|
||||
use std::io::{self, Write};
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::time::Instant;
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
io::{self, Write},
|
||||
path::Path,
|
||||
sync::Arc,
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
use grep_matcher::Matcher;
|
||||
use grep_searcher::{Searcher, Sink, SinkError, SinkFinish, SinkMatch};
|
||||
use termcolor::{ColorSpec, NoColor, WriteColor};
|
||||
use {
|
||||
grep_matcher::Matcher,
|
||||
grep_searcher::{Searcher, Sink, SinkError, SinkFinish, SinkMatch},
|
||||
termcolor::{ColorSpec, NoColor, WriteColor},
|
||||
};
|
||||
|
||||
use crate::color::ColorSpecs;
|
||||
use crate::counter::CounterWriter;
|
||||
use crate::hyperlink::{HyperlinkPattern, HyperlinkSpan};
|
||||
use crate::stats::Stats;
|
||||
use crate::util::{find_iter_at_in_context, PrinterPath};
|
||||
use crate::{
|
||||
color::ColorSpecs,
|
||||
counter::CounterWriter,
|
||||
hyperlink::{HyperlinkPattern, HyperlinkSpan},
|
||||
stats::Stats,
|
||||
util::{find_iter_at_in_context, PrinterPath},
|
||||
};
|
||||
|
||||
/// The configuration for the summary printer.
|
||||
///
|
||||
@ -392,13 +398,13 @@ impl<W: WriteColor> Summary<W> {
|
||||
None
|
||||
};
|
||||
SummarySink {
|
||||
matcher: matcher,
|
||||
matcher,
|
||||
summary: self,
|
||||
path: None,
|
||||
start_time: Instant::now(),
|
||||
match_count: 0,
|
||||
binary_byte_offset: None,
|
||||
stats: stats,
|
||||
stats,
|
||||
}
|
||||
}
|
||||
|
||||
@ -428,13 +434,13 @@ impl<W: WriteColor> Summary<W> {
|
||||
self.config.separator_path,
|
||||
);
|
||||
SummarySink {
|
||||
matcher: matcher,
|
||||
matcher,
|
||||
summary: self,
|
||||
path: Some(ppath),
|
||||
start_time: Instant::now(),
|
||||
match_count: 0,
|
||||
binary_byte_offset: None,
|
||||
stats: stats,
|
||||
stats,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +1,24 @@
|
||||
use std::borrow::Cow;
|
||||
use std::cell::OnceCell;
|
||||
use std::path::Path;
|
||||
use std::time;
|
||||
use std::{fmt, io};
|
||||
use std::{borrow::Cow, fmt, io, path::Path, time};
|
||||
|
||||
use bstr::{ByteSlice, ByteVec};
|
||||
use grep_matcher::{Captures, LineTerminator, Match, Matcher};
|
||||
use grep_searcher::{
|
||||
LineIter, Searcher, SinkContext, SinkContextKind, SinkError, SinkMatch,
|
||||
use {
|
||||
bstr::{ByteSlice, ByteVec},
|
||||
grep_matcher::{Captures, LineTerminator, Match, Matcher},
|
||||
grep_searcher::{
|
||||
LineIter, Searcher, SinkContext, SinkContextKind, SinkError, SinkMatch,
|
||||
},
|
||||
termcolor::HyperlinkSpec,
|
||||
};
|
||||
#[cfg(feature = "serde1")]
|
||||
use serde::{Serialize, Serializer};
|
||||
use termcolor::HyperlinkSpec;
|
||||
|
||||
use crate::hyperlink::{HyperlinkPath, HyperlinkPattern, HyperlinkValues};
|
||||
use crate::MAX_LOOK_AHEAD;
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Serialize, Serializer};
|
||||
|
||||
use crate::{
|
||||
hyperlink::{HyperlinkPath, HyperlinkPattern, HyperlinkValues},
|
||||
MAX_LOOK_AHEAD,
|
||||
};
|
||||
|
||||
/// A type for handling replacements while amortizing allocation.
|
||||
pub struct Replacer<M: Matcher> {
|
||||
pub(crate) struct Replacer<M: Matcher> {
|
||||
space: Option<Space<M>>,
|
||||
}
|
||||
|
||||
@ -45,7 +46,7 @@ impl<M: Matcher> Replacer<M> {
|
||||
///
|
||||
/// This constructor does not allocate. Instead, space for dealing with
|
||||
/// replacements is allocated lazily only when needed.
|
||||
pub fn new() -> Replacer<M> {
|
||||
pub(crate) fn new() -> Replacer<M> {
|
||||
Replacer { space: None }
|
||||
}
|
||||
|
||||
@ -54,7 +55,7 @@ impl<M: Matcher> Replacer<M> {
|
||||
/// replacement, use the `replacement` method.
|
||||
///
|
||||
/// This can fail if the underlying matcher reports an error.
|
||||
pub fn replace_all<'a>(
|
||||
pub(crate) fn replace_all<'a>(
|
||||
&'a mut self,
|
||||
searcher: &Searcher,
|
||||
matcher: &M,
|
||||
@ -112,7 +113,9 @@ impl<M: Matcher> Replacer<M> {
|
||||
/// all replacement occurrences within the returned replacement buffer.
|
||||
///
|
||||
/// If no replacement has occurred then `None` is returned.
|
||||
pub fn replacement<'a>(&'a self) -> Option<(&'a [u8], &'a [Match])> {
|
||||
pub(crate) fn replacement<'a>(
|
||||
&'a self,
|
||||
) -> Option<(&'a [u8], &'a [Match])> {
|
||||
match self.space {
|
||||
None => None,
|
||||
Some(ref space) => {
|
||||
@ -129,7 +132,7 @@ impl<M: Matcher> Replacer<M> {
|
||||
///
|
||||
/// Subsequent calls to `replacement` after calling `clear` (but before
|
||||
/// executing another replacement) will always return `None`.
|
||||
pub fn clear(&mut self) {
|
||||
pub(crate) fn clear(&mut self) {
|
||||
if let Some(ref mut space) = self.space {
|
||||
space.dst.clear();
|
||||
space.matches.clear();
|
||||
@ -145,8 +148,7 @@ impl<M: Matcher> Replacer<M> {
|
||||
if self.space.is_none() {
|
||||
let caps =
|
||||
matcher.new_captures().map_err(io::Error::error_message)?;
|
||||
self.space =
|
||||
Some(Space { caps: caps, dst: vec![], matches: vec![] });
|
||||
self.space = Some(Space { caps, dst: vec![], matches: vec![] });
|
||||
}
|
||||
Ok(self.space.as_mut().unwrap())
|
||||
}
|
||||
@ -165,7 +167,7 @@ impl<M: Matcher> Replacer<M> {
|
||||
/// results of the replacement instead of the bytes reported directly by the
|
||||
/// searcher.
|
||||
#[derive(Debug)]
|
||||
pub struct Sunk<'a> {
|
||||
pub(crate) struct Sunk<'a> {
|
||||
bytes: &'a [u8],
|
||||
absolute_byte_offset: u64,
|
||||
line_number: Option<u64>,
|
||||
@ -176,7 +178,7 @@ pub struct Sunk<'a> {
|
||||
|
||||
impl<'a> Sunk<'a> {
|
||||
#[inline]
|
||||
pub fn empty() -> Sunk<'static> {
|
||||
pub(crate) fn empty() -> Sunk<'static> {
|
||||
Sunk {
|
||||
bytes: &[],
|
||||
absolute_byte_offset: 0,
|
||||
@ -188,7 +190,7 @@ impl<'a> Sunk<'a> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_sink_match(
|
||||
pub(crate) fn from_sink_match(
|
||||
sunk: &'a SinkMatch<'a>,
|
||||
original_matches: &'a [Match],
|
||||
replacement: Option<(&'a [u8], &'a [Match])>,
|
||||
@ -196,17 +198,17 @@ impl<'a> Sunk<'a> {
|
||||
let (bytes, matches) =
|
||||
replacement.unwrap_or_else(|| (sunk.bytes(), original_matches));
|
||||
Sunk {
|
||||
bytes: bytes,
|
||||
bytes,
|
||||
absolute_byte_offset: sunk.absolute_byte_offset(),
|
||||
line_number: sunk.line_number(),
|
||||
context_kind: None,
|
||||
matches: matches,
|
||||
original_matches: original_matches,
|
||||
matches,
|
||||
original_matches,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_sink_context(
|
||||
pub(crate) fn from_sink_context(
|
||||
sunk: &'a SinkContext<'a>,
|
||||
original_matches: &'a [Match],
|
||||
replacement: Option<(&'a [u8], &'a [Match])>,
|
||||
@ -214,47 +216,47 @@ impl<'a> Sunk<'a> {
|
||||
let (bytes, matches) =
|
||||
replacement.unwrap_or_else(|| (sunk.bytes(), original_matches));
|
||||
Sunk {
|
||||
bytes: bytes,
|
||||
bytes,
|
||||
absolute_byte_offset: sunk.absolute_byte_offset(),
|
||||
line_number: sunk.line_number(),
|
||||
context_kind: Some(sunk.kind()),
|
||||
matches: matches,
|
||||
original_matches: original_matches,
|
||||
matches,
|
||||
original_matches,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn context_kind(&self) -> Option<&'a SinkContextKind> {
|
||||
pub(crate) fn context_kind(&self) -> Option<&'a SinkContextKind> {
|
||||
self.context_kind
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn bytes(&self) -> &'a [u8] {
|
||||
pub(crate) fn bytes(&self) -> &'a [u8] {
|
||||
self.bytes
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn matches(&self) -> &'a [Match] {
|
||||
pub(crate) fn matches(&self) -> &'a [Match] {
|
||||
self.matches
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn original_matches(&self) -> &'a [Match] {
|
||||
pub(crate) fn original_matches(&self) -> &'a [Match] {
|
||||
self.original_matches
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn lines(&self, line_term: u8) -> LineIter<'a> {
|
||||
pub(crate) fn lines(&self, line_term: u8) -> LineIter<'a> {
|
||||
LineIter::new(line_term, self.bytes())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn absolute_byte_offset(&self) -> u64 {
|
||||
pub(crate) fn absolute_byte_offset(&self) -> u64 {
|
||||
self.absolute_byte_offset
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn line_number(&self) -> Option<u64> {
|
||||
pub(crate) fn line_number(&self) -> Option<u64> {
|
||||
self.line_number
|
||||
}
|
||||
}
|
||||
@ -281,7 +283,7 @@ impl<'a> Sunk<'a> {
|
||||
pub struct PrinterPath<'a> {
|
||||
path: &'a Path,
|
||||
bytes: Cow<'a, [u8]>,
|
||||
hyperlink_path: OnceCell<Option<HyperlinkPath>>,
|
||||
hyperlink_path: std::cell::OnceCell<Option<HyperlinkPath>>,
|
||||
}
|
||||
|
||||
impl<'a> PrinterPath<'a> {
|
||||
@ -290,7 +292,7 @@ impl<'a> PrinterPath<'a> {
|
||||
PrinterPath {
|
||||
path,
|
||||
bytes: Vec::from_path_lossy(path),
|
||||
hyperlink_path: OnceCell::new(),
|
||||
hyperlink_path: std::cell::OnceCell::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -331,8 +333,8 @@ impl<'a> PrinterPath<'a> {
|
||||
&self.bytes
|
||||
}
|
||||
|
||||
/// Creates a hyperlink for this path and the given line and column, using the specified
|
||||
/// pattern. Uses the given buffer to store the hyperlink.
|
||||
/// Creates a hyperlink for this path and the given line and column, using
|
||||
/// the specified pattern. Uses the given buffer to store the hyperlink.
|
||||
pub fn create_hyperlink_spec<'b>(
|
||||
&self,
|
||||
pattern: &HyperlinkPattern,
|
||||
@ -365,7 +367,7 @@ impl<'a> PrinterPath<'a> {
|
||||
/// with the Deserialize impl for std::time::Duration, since this type only
|
||||
/// adds new fields.
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
||||
pub struct NiceDuration(pub time::Duration);
|
||||
pub(crate) struct NiceDuration(pub time::Duration);
|
||||
|
||||
impl fmt::Display for NiceDuration {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
@ -383,7 +385,7 @@ impl NiceDuration {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde1")]
|
||||
#[cfg(feature = "serde")]
|
||||
impl Serialize for NiceDuration {
|
||||
fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
|
||||
use serde::ser::SerializeStruct;
|
||||
@ -401,7 +403,7 @@ impl Serialize for NiceDuration {
|
||||
///
|
||||
/// This stops trimming a prefix as soon as it sees non-whitespace or a line
|
||||
/// terminator.
|
||||
pub fn trim_ascii_prefix(
|
||||
pub(crate) fn trim_ascii_prefix(
|
||||
line_term: LineTerminator,
|
||||
slice: &[u8],
|
||||
range: Match,
|
||||
@ -422,7 +424,7 @@ pub fn trim_ascii_prefix(
|
||||
range.with_start(range.start() + count)
|
||||
}
|
||||
|
||||
pub fn find_iter_at_in_context<M, F>(
|
||||
pub(crate) fn find_iter_at_in_context<M, F>(
|
||||
searcher: &Searcher,
|
||||
matcher: M,
|
||||
mut bytes: &[u8],
|
||||
@ -482,7 +484,7 @@ where
|
||||
/// Given a buf and some bounds, if there is a line terminator at the end of
|
||||
/// the given bounds in buf, then the bounds are trimmed to remove the line
|
||||
/// terminator.
|
||||
pub fn trim_line_terminator(
|
||||
pub(crate) fn trim_line_terminator(
|
||||
searcher: &Searcher,
|
||||
buf: &[u8],
|
||||
line: &mut Match,
|
||||
|
Loading…
Reference in New Issue
Block a user