expr.rs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. //! pretty printer for rsx!
  2. use std::fmt::{Result, Write};
  3. use proc_macro2::Span;
  4. use crate::Writer;
  5. impl Writer<'_> {
  6. pub fn write_raw_expr(&mut self, placement: Span) -> Result {
  7. /*
  8. We want to normalize the expr to the appropriate indent level.
  9. */
  10. let start = placement.start();
  11. let end = placement.end();
  12. // if the expr is on one line, just write it directly
  13. if start.line == end.line {
  14. write!(
  15. self.out,
  16. "{}",
  17. &self.src[start.line - 1][start.column - 1..end.column].trim()
  18. )?;
  19. return Ok(());
  20. }
  21. // If the expr is multiline, we want to collect all of its lines together and write them out properly
  22. // This involves unshifting the first line if it's aligned
  23. let first_line = &self.src[start.line - 1];
  24. write!(
  25. self.out,
  26. "{}",
  27. &first_line[start.column - 1..first_line.len()].trim()
  28. )?;
  29. let first_prefix = &self.src[start.line - 1][..start.column];
  30. let offset = match first_prefix.trim() {
  31. "" => 0,
  32. _ => first_prefix
  33. .chars()
  34. .rev()
  35. .take_while(|c| c.is_whitespace())
  36. .count() as isize,
  37. };
  38. for (id, line) in self.src[start.line..end.line].iter().enumerate() {
  39. writeln!(self.out)?;
  40. // trim the leading whitespace
  41. let line = match id {
  42. x if x == (end.line - start.line) - 1 => &line[..end.column],
  43. _ => line,
  44. };
  45. if offset < 0 {
  46. for _ in 0..-offset {
  47. write!(self.out, " ")?;
  48. }
  49. write!(self.out, "{}", line)?;
  50. } else {
  51. let offset = offset as usize;
  52. let right = &line[offset..];
  53. write!(self.out, "{}", right)?;
  54. }
  55. }
  56. Ok(())
  57. }
  58. }