From 5f0a1e67c64082c848418daa2b51020eb42c5c12 Mon Sep 17 00:00:00 2001 From: Akshay Date: Mon, 25 Oct 2021 22:08:52 +0530 Subject: rework cli, use subcommands instead --- bin/src/fix/single.rs | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 bin/src/fix/single.rs (limited to 'bin/src/fix/single.rs') diff --git a/bin/src/fix/single.rs b/bin/src/fix/single.rs new file mode 100644 index 0000000..d430693 --- /dev/null +++ b/bin/src/fix/single.rs @@ -0,0 +1,59 @@ +use std::{borrow::Cow, convert::TryFrom}; + +use lib::{Report, LINTS}; +use rnix::{TextRange, TextSize}; + +use crate::err::SingleFixErr; +use crate::fix::Source; + +pub struct SingleFixResult<'δ> { + pub src: Source<'δ>, +} + +fn pos_to_byte(line: usize, col: usize, src: &str) -> Result { + let mut byte: TextSize = TextSize::of(""); + for (_, l) in src.lines().enumerate().take_while(|(i, _)| i <= &line) { + byte += TextSize::of(l); + } + byte += TextSize::try_from(col).map_err(|_| SingleFixErr::Conversion(col))?; + + if usize::from(byte) >= src.len() { + Err(SingleFixErr::OutOfBounds(line, col)) + } else { + Ok(byte) + } +} + +fn find(offset: TextSize, src: &str) -> Result { + // we don't really need the source to form a completely parsed tree + let parsed = rnix::parse(src); + + let elem_at = parsed + .node() + .child_or_token_at_range(TextRange::empty(offset)) + .ok_or(SingleFixErr::NoOp)?; + + LINTS + .get(&elem_at.kind()) + .map(|rules| { + rules + .iter() + .filter_map(|rule| rule.validate(&elem_at)) + .filter(|report| report.total_suggestion_range().is_some()) + .next() + }) + .flatten() + .ok_or(SingleFixErr::NoOp) +} + +pub fn single(line: usize, col: usize, src: &str) -> Result { + let mut src = Cow::from(src); + let offset = pos_to_byte(line, col, &*src)?; + let report = find(offset, &*src)?; + + report.apply(src.to_mut()); + + Ok(SingleFixResult { + src + }) +} -- cgit v1.2.3