Skip to content

Commit

Permalink
Replaced textwrap package with custom implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
ross-byrne authored and lpil committed Dec 2, 2024
1 parent e20bbf4 commit 0b2cf1b
Show file tree
Hide file tree
Showing 37 changed files with 195 additions and 107 deletions.
35 changes: 0 additions & 35 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions compiler-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ capnp = "0"
# Template rendering
askama = "0"
# Markdown parsing
pulldown-cmark = { version = "0", default-features = false, features = ["html"] }
pulldown-cmark = { version = "0", default-features = false, features = [
"html",
] }
# Non-empty vectors
vec1 = "1"
# XDG directory locations
dirs-next = "2"
# Helper for wrapping text onto lines based upon width
textwrap = { version = "=0.15.0", features = ["terminal_size"] }
# SPDX license parsing
spdx = "0"
# Binary format de-serialization
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
source: compiler-core/src/erlang/tests/external_fn.rs
expression: "\n// This will error for having no support on this platform\n@external(erlang, \"one\", \"two\")\npub fn no_impl() -> Int\n\npub fn main() {\n // This will due to no_impl not having an appropriate implementation for the\n // target, NOT because it doesn't exist. The analyser should still know about\n // it, even though it is invalid.\n no_impl()\n}\n"
snapshot_kind: text
---
----- SOURCE CODE

Expand All @@ -23,8 +24,8 @@ error: Unsupported target
4pub fn no_impl() -> Int
^^^^^^^^^^^^^^^^

The `no_impl` function is public but doesn't have an implementation for
the JavaScript target. All public functions of a package must be able to
The `no_impl` function is public but doesn't have an implementation for the
JavaScript target. All public functions of a package must be able to
compile for a module to be valid.

error: Unsupported target
Expand Down
91 changes: 90 additions & 1 deletion compiler-core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use itertools::Itertools;
use pubgrub::package::Package;
use pubgrub::report::DerivationTree;
use pubgrub::version::Version;
use std::borrow::Cow;
use std::collections::HashSet;
use std::env;
use std::fmt::{Debug, Display};
Expand Down Expand Up @@ -3873,5 +3874,93 @@ pub struct Unformatted {
}

pub fn wrap(text: &str) -> String {
textwrap::fill(text, std::cmp::min(75, textwrap::termwidth()))
let mut result = String::with_capacity(text.len());

for (i, line) in wrap_text(text, 75).iter().enumerate() {
if i > 0 {
result.push('\n');
}
result.push_str(line);
}

result
}

fn wrap_text(text: &str, width: usize) -> Vec<Cow<'_, str>> {
let mut lines: Vec<Cow<'_, str>> = Vec::new();
for line in text.split('\n') {
// check if line needs to be broken
match line.len() > width {
false => lines.push(Cow::from(line)),
true => {
let mut new_lines = break_line(line, width);
lines.append(&mut new_lines);
}
};
}

lines
}

fn break_line(line: &str, width: usize) -> Vec<Cow<'_, str>> {
let mut lines: Vec<Cow<'_, str>> = Vec::new();
let mut newline = String::from("");

// split line by spaces
for (i, word) in line.split(' ').enumerate() {
let is_new_line = i < 1 || newline.is_empty();

let can_add_word = match is_new_line {
true => newline.len() + word.len() <= width,
// +1 accounts for space added before word
false => newline.len() + (word.len() + 1) <= width,
};

if can_add_word {
if !is_new_line {
newline.push(' ');
}
newline.push_str(word);
} else {
// word too big, save existing line if present
if !newline.is_empty() {
// save current line and reset it
lines.push(Cow::from(newline.to_owned()));
newline.clear();
}

// then save word to a new line or break it
match word.len() > width {
false => newline.push_str(word),
true => {
let (mut newlines, remainder) = break_word(word, width);
lines.append(&mut newlines);
newline.push_str(remainder);
}
}
}
}

// save last line after loop finishes
if !newline.is_empty() {
lines.push(Cow::from(newline));
}

lines
}

// breaks word into n lines based on width. Returns list of new lines and remainder
fn break_word(word: &str, width: usize) -> (Vec<Cow<'_, str>>, &str) {
let mut new_lines: Vec<Cow<'_, str>> = Vec::new();
let (first, mut remainder) = word.split_at(width);
new_lines.push(Cow::from(first));

// split remainder until it's small enough
while remainder.len() > width {
let (first, second) = remainder.split_at(width);
new_lines.push(Cow::from(first));
remainder = second;
}

(new_lines, remainder)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
source: compiler-core/src/type_/tests.rs
expression: "\npub type Wibble {\n Wibble(a: Int, b: Int)\n Wobble(a: Int, c: String)\n}\n\npub fn main() {\n let a = case todo {\n Wibble(..) as b -> Wibble(..b, b: 1)\n Wobble(..) as b -> Wobble(..b, c: \"a\")\n }\n\n a.b\n}\n"
snapshot_kind: text
---
----- SOURCE CODE

Expand Down Expand Up @@ -36,6 +37,6 @@ It has these accessible fields:

Note: The field you are trying to access might not be consistently present
or positioned across the custom type's variants, preventing reliable
access. Ensure the field exists in the same position and has the same
type in all variants, or pattern matching on it to enable direct accessor
access. Ensure the field exists in the same position and has the same type
in all variants, or pattern matching on it to enable direct accessor
syntax.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
source: compiler-core/src/type_/tests.rs
expression: "\npub type Thingy {\n A(a: Int)\n B(x: Int, b: Int)\n}\n\npub fn fun(x) {\n case x {\n A(..) -> x.a\n B(..) -> x.b\n }\n x.b\n}\n"
snapshot_kind: text
---
----- SOURCE CODE

Expand Down Expand Up @@ -33,6 +34,6 @@ It does not have any fields shared by all variants.

Note: The field you are trying to access might not be consistently present
or positioned across the custom type's variants, preventing reliable
access. Ensure the field exists in the same position and has the same
type in all variants, or pattern matching on it to enable direct accessor
access. Ensure the field exists in the same position and has the same type
in all variants, or pattern matching on it to enable direct accessor
syntax.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
source: compiler-core/src/type_/tests/errors.rs
expression: "\npub type Person {\n Teacher(name: String, title: String, age: Int)\n Student(name: String, age: Int)\n}\npub fn get_name(person: Person) { person.name }\npub fn get_age(person: Person) { person.age }"
snapshot_kind: text
---
----- SOURCE CODE

Expand Down Expand Up @@ -28,6 +29,6 @@ It has these accessible fields:

Note: The field you are trying to access might not be consistently present
or positioned across the custom type's variants, preventing reliable
access. Ensure the field exists in the same position and has the same
type in all variants, or pattern matching on it to enable direct accessor
access. Ensure the field exists in the same position and has the same type
in all variants, or pattern matching on it to enable direct accessor
syntax.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
source: compiler-core/src/type_/tests/errors.rs
expression: "\npub type Person {\n Teacher(title: String, age: Int, name: String)\n Student(name: String, age: Int)\n}\npub fn get_name(person: Person) { person.name }\npub fn get_age(person: Person) { person.age }"
snapshot_kind: text
---
----- SOURCE CODE

Expand Down Expand Up @@ -28,6 +29,6 @@ It has these accessible fields:

Note: The field you are trying to access might not be consistently present
or positioned across the custom type's variants, preventing reliable
access. Ensure the field exists in the same position and has the same
type in all variants, or pattern matching on it to enable direct accessor
access. Ensure the field exists in the same position and has the same type
in all variants, or pattern matching on it to enable direct accessor
syntax.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
source: compiler-core/src/type_/tests/errors.rs
expression: "\npub type Person {\n Teacher(name: String, age: Int, title: String)\n Student(name: String, age: Int)\n}\npub fn get_title(person: Person) { person.title }"
snapshot_kind: text
---
----- SOURCE CODE

Expand Down Expand Up @@ -28,6 +29,6 @@ It has these accessible fields:

Note: The field you are trying to access might not be consistently present
or positioned across the custom type's variants, preventing reliable
access. Ensure the field exists in the same position and has the same
type in all variants, or pattern matching on it to enable direct accessor
access. Ensure the field exists in the same position and has the same type
in all variants, or pattern matching on it to enable direct accessor
syntax.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
source: compiler-core/src/type_/tests/errors.rs
expression: "\npub type Shape {\n Square(x: Int, y: Int)\n Rectangle(x: String, y: String)\n}\npub fn get_x(shape: Shape) { shape.x }\n"
snapshot_kind: text
---
----- SOURCE CODE

Expand All @@ -26,6 +27,6 @@ It does not have any fields shared by all variants.

Note: The field you are trying to access might not be consistently present
or positioned across the custom type's variants, preventing reliable
access. Ensure the field exists in the same position and has the same
type in all variants, or pattern matching on it to enable direct accessor
access. Ensure the field exists in the same position and has the same type
in all variants, or pattern matching on it to enable direct accessor
syntax.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
source: compiler-core/src/type_/tests/errors.rs
expression: let assert <<bitValue>> = <<73>>
snapshot_kind: text
---
----- SOURCE CODE
let assert <<bitValue>> = <<73>>
Expand All @@ -12,6 +13,6 @@ error: Invalid variable name
1let assert <<bitValue>> = <<73>>
^^^^^^^^ This is not a valid variable name

Hint: Variable names start with a lowercase letter and contain a-z, 0-9,
or _.
Hint: Variable names start with a lowercase letter and contain a-z, 0-9, or
_.
Try: bit_value
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
source: compiler-core/src/type_/tests/errors.rs
expression: "case 21 { twentyOne -> {Nil} }"
snapshot_kind: text
---
----- SOURCE CODE
case 21 { twentyOne -> {Nil} }
Expand All @@ -12,6 +13,6 @@ error: Invalid variable name
1case 21 { twentyOne -> {Nil} }
^^^^^^^^^ This is not a valid variable name

Hint: Variable names start with a lowercase letter and contain a-z, 0-9,
or _.
Hint: Variable names start with a lowercase letter and contain a-z, 0-9, or
_.
Try: twenty_one
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
source: compiler-core/src/type_/tests/errors.rs
expression: const myInvalid_Constant = 42
snapshot_kind: text
---
----- SOURCE CODE
const myInvalid_Constant = 42
Expand All @@ -12,6 +13,6 @@ error: Invalid constant name
1const myInvalid_Constant = 42
^^^^^^^^^^^^^^^^^^ This is not a valid constant name

Hint: Constant names start with a lowercase letter and contain a-z, 0-9,
or _.
Hint: Constant names start with a lowercase letter and contain a-z, 0-9, or
_.
Try: my_invalid_constant
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
source: compiler-core/src/type_/tests/errors.rs
expression: "pub type Box { Box(Int) } pub fn main() { let Box(innerValue) = Box(203) }"
snapshot_kind: text
---
----- SOURCE CODE
pub type Box { Box(Int) } pub fn main() { let Box(innerValue) = Box(203) }
Expand All @@ -12,6 +13,6 @@ error: Invalid variable name
1pub type Box { Box(Int) } pub fn main() { let Box(innerValue) = Box(203) }
│ ^^^^^^^^^^ This is not a valid variable name

Hint: Variable names start with a lowercase letter and contain a-z, 0-9,
or _.
Hint: Variable names start with a lowercase letter and contain a-z, 0-9, or
_.
Try: inner_value
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
source: compiler-core/src/type_/tests/errors.rs
expression: "fn doStuff() {}"
snapshot_kind: text
---
----- SOURCE CODE
fn doStuff() {}
Expand All @@ -12,6 +13,6 @@ error: Invalid function name
1 │ fn doStuff() {}
^^^^^^^ This is not a valid function name

Hint: Function names start with a lowercase letter and contain a-z, 0-9,
or _.
Hint: Function names start with a lowercase letter and contain a-z, 0-9, or
_.
Try: do_stuff
Loading

0 comments on commit 0b2cf1b

Please sign in to comment.