-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce a trait for WrapAlgorithm
#325
Labels
Comments
mgeisler
added a commit
that referenced
this issue
May 1, 2021
In #219, the type parameter for `Options` was relaxed to `?Sized`, which means that `Options<T>` can be a dynamically-sized type by using `dyn WordSplitter` as the type parameter. This allows code to freely assign both boxed and unboxed `WordSplitter`s to the same variable: ```rust let mut dynamic_opt: Box<Options<dyn WordSplitter>>; dynamic_opt = Box::new(Options::with_splitter(20, NoHyphenation)); dynamic_opt = Box::new(Options::with_splitter(20, Box::new(NoHyphenation))); ``` In both cases, dynamic dispatch would be used at runtime. This was called “proper outer boxing” in #219 and #215. By only boxing the word splitter (so-called “inner boxing”), the outer layer of indirection can be removed: ```rust let mut dynamic_opt: Options<Box<dyn WordSplitter>>; dynamic_opt = Options::with_splitter(20, Box::new(NoHyphenation)); dynamic_opt = Options::with_splitter(20, Box::new(HyphenSplitter)); ``` This also used dynamic dispatch at runtime. Static dispatching was also possible by using a fixed type. Trying to change the word splitter type is a compile time error: ```rust let mut static_opt: Options<NoHyphenation>; static_opt = Options::with_splitter(10, NoHyphenation); static_opt = Options::with_splitter(20, HyphenSplitter); // <- error! ``` In order to add a trait for the `WrapAlgorithm` enum (see #325), we’re now removing the `?Sized` bound on the `WordSplitter` type parameter. This makes the first block above a compile time error and you must now choose upfront between boxed and unboxed word splitters. If you choose a boxed word splitter (second example), then you get dynamic dispatch and can freely change the word splitter at runtime. If you choose an unboxed wordsplitter, you get static dispatch and cannot change the word splitter later. This change seems necessary since we will be adding more type parameters to the `Options` struct: one for the wrapping algorithm used and one for how we find words (splitting by space or by the full Unicode line breaking algorithm). Since both dynamic and static dispatch remains possible, this change should not cause big problems for Textwrap clients.
mgeisler
added a commit
that referenced
this issue
May 1, 2021
In #219, the type parameter for `Options` was relaxed to `?Sized`, which means that `Options<T>` can be a dynamically-sized type by using `dyn WordSplitter` as the type parameter. This allows code to freely assign both boxed and unboxed `WordSplitter`s to the same variable: ```rust let mut dynamic_opt: Box<Options<dyn WordSplitter>>; dynamic_opt = Box::new(Options::with_splitter(20, NoHyphenation)); dynamic_opt = Box::new(Options::with_splitter(20, Box::new(NoHyphenation))); ``` In both cases, dynamic dispatch would be used at runtime. This was called “proper outer boxing” in #219 and #215. By only boxing the word splitter (so-called “inner boxing”), the outer layer of indirection can be removed: ```rust let mut dynamic_opt: Options<Box<dyn WordSplitter>>; dynamic_opt = Options::with_splitter(20, Box::new(NoHyphenation)); dynamic_opt = Options::with_splitter(20, Box::new(HyphenSplitter)); ``` This also used dynamic dispatch at runtime. Static dispatching was also possible by using a fixed type. Trying to change the word splitter type is a compile time error: ```rust let mut static_opt: Options<NoHyphenation>; static_opt = Options::with_splitter(10, NoHyphenation); static_opt = Options::with_splitter(20, HyphenSplitter); // <- error! ``` In order to add a trait for the `WrapAlgorithm` enum (see #325), we’re now removing the `?Sized` bound on the `WordSplitter` type parameter. This makes the first block above a compile time error and you must now choose upfront between boxed and unboxed word splitters. If you choose a boxed word splitter (second example), then you get dynamic dispatch and can freely change the word splitter at runtime. If you choose an unboxed wordsplitter, you get static dispatch and cannot change the word splitter later. This change seems necessary since we will be adding more type parameters to the `Options` struct: one for the wrapping algorithm used and one for how we find words (splitting by space or by the full Unicode line breaking algorithm). Since both dynamic and static dispatch remains possible, this change should not cause big problems for Textwrap clients.
mgeisler
added a commit
that referenced
this issue
May 1, 2021
In #219, the type parameter for `Options` was relaxed to `?Sized`, which means that `Options<T>` can be a dynamically-sized type by using `dyn WordSplitter` as the type parameter. This allows code to freely assign both boxed and unboxed `WordSplitter`s to the same variable: ```rust let mut dynamic_opt: Box<Options<dyn WordSplitter>>; dynamic_opt = Box::new(Options::with_splitter(20, NoHyphenation)); dynamic_opt = Box::new(Options::with_splitter(20, Box::new(NoHyphenation))); ``` In both cases, dynamic dispatch would be used at runtime. This was called “proper outer boxing” in #219 and #215. By only boxing the word splitter (so-called “inner boxing”), the outer layer of indirection can be removed: ```rust let mut dynamic_opt: Options<Box<dyn WordSplitter>>; dynamic_opt = Options::with_splitter(20, Box::new(NoHyphenation)); dynamic_opt = Options::with_splitter(20, Box::new(HyphenSplitter)); ``` This also used dynamic dispatch at runtime. Static dispatching was also possible by using a fixed type. Trying to change the word splitter type is a compile time error: ```rust let mut static_opt: Options<NoHyphenation>; static_opt = Options::with_splitter(10, NoHyphenation); static_opt = Options::with_splitter(20, HyphenSplitter); // <- error! ``` In order to add a trait for the `WrapAlgorithm` enum (see #325), we’re now removing the `?Sized` bound on the `WordSplitter` type parameter. This makes the first block above a compile time error and you must now choose upfront between boxed and unboxed word splitters. If you choose a boxed word splitter (second example), then you get dynamic dispatch and can freely change the word splitter at runtime. If you choose an unboxed wordsplitter, you get static dispatch and cannot change the word splitter later. This change seems necessary since we will be adding more type parameters to the `Options` struct: one for the wrapping algorithm used and one for how we find words (splitting by space or by the full Unicode line breaking algorithm). Since both dynamic and static dispatch remains possible, this change should not cause big problems for Textwrap clients.
mgeisler
added a commit
that referenced
this issue
May 1, 2021
In #219, the type parameter for `Options` was relaxed to `?Sized`, which means that `Options<T>` can be a dynamically-sized type by using `dyn WordSplitter` as the type parameter. This allows code to freely assign both boxed and unboxed `WordSplitter`s to the same variable: ```rust let mut dynamic_opt: Box<Options<dyn WordSplitter>>; dynamic_opt = Box::new(Options::with_splitter(20, NoHyphenation)); dynamic_opt = Box::new(Options::with_splitter(20, Box::new(NoHyphenation))); ``` In both cases, dynamic dispatch would be used at runtime. This was called “proper outer boxing” in #219 and #215. By only boxing the word splitter (so-called “inner boxing”), the outer layer of indirection can be removed: ```rust let mut dynamic_opt: Options<Box<dyn WordSplitter>>; dynamic_opt = Options::with_splitter(20, Box::new(NoHyphenation)); dynamic_opt = Options::with_splitter(20, Box::new(HyphenSplitter)); ``` This also used dynamic dispatch at runtime. Static dispatching was also possible by using a fixed type. Trying to change the word splitter type is a compile time error: ```rust let mut static_opt: Options<NoHyphenation>; static_opt = Options::with_splitter(10, NoHyphenation); static_opt = Options::with_splitter(20, HyphenSplitter); // <- error! ``` In order to add a trait for the `WrapAlgorithm` enum (see #325), we’re now removing the `?Sized` bound on the `WordSplitter` type parameter. This makes the first block above a compile time error and you must now choose upfront between boxed and unboxed word splitters. If you choose a boxed word splitter (second example), then you get dynamic dispatch and can freely change the word splitter at runtime. If you choose an unboxed wordsplitter, you get static dispatch and cannot change the word splitter later. This change seems necessary since we will be adding more type parameters to the `Options` struct: one for the wrapping algorithm used and one for how we find words (splitting by space or by the full Unicode line breaking algorithm). Since both dynamic and static dispatch remains possible, this change should not cause big problems for Textwrap clients.
mgeisler
added a commit
that referenced
this issue
May 1, 2021
In #219, the type parameter for `Options` was relaxed to `?Sized`, which means that `Options<T>` can be a dynamically-sized type by using `dyn WordSplitter` as the type parameter. This allows code to freely assign both boxed and unboxed `WordSplitter`s to the same variable: ```rust let mut dynamic_opt: Box<Options<dyn WordSplitter>>; dynamic_opt = Box::new(Options::with_splitter(20, NoHyphenation)); dynamic_opt = Box::new(Options::with_splitter(20, Box::new(NoHyphenation))); ``` In both cases, dynamic dispatch would be used at runtime. This was called “proper outer boxing” in #219 and #215. By only boxing the word splitter (so-called “inner boxing”), the outer layer of indirection can be removed: ```rust let mut dynamic_opt: Options<Box<dyn WordSplitter>>; dynamic_opt = Options::with_splitter(20, Box::new(NoHyphenation)); dynamic_opt = Options::with_splitter(20, Box::new(HyphenSplitter)); ``` This also used dynamic dispatch at runtime. Static dispatching was also possible by using a fixed type. Trying to change the word splitter type is a compile time error: ```rust let mut static_opt: Options<NoHyphenation>; static_opt = Options::with_splitter(10, NoHyphenation); static_opt = Options::with_splitter(20, HyphenSplitter); // <- error! ``` In order to add a trait for the `WrapAlgorithm` enum (see #325), we’re now removing the `?Sized` bound on the `WordSplitter` type parameter. This makes the first block above a compile time error and you must now choose upfront between boxed and unboxed word splitters. If you choose a boxed word splitter (second example), then you get dynamic dispatch and can freely change the word splitter at runtime. If you choose an unboxed wordsplitter, you get static dispatch and cannot change the word splitter later. This change seems necessary since we will be adding more type parameters to the `Options` struct: one for the wrapping algorithm used and one for how we find words (splitting by space or by the full Unicode line breaking algorithm). Since both dynamic and static dispatch remains possible, this change should not cause big problems for Textwrap clients.
mgeisler
added a commit
that referenced
this issue
May 1, 2021
In #219, the type parameter for `Options` was relaxed to `?Sized`, which means that `Options<T>` can be a dynamically-sized type by using `dyn WordSplitter` as the type parameter. This allows code to freely assign both boxed and unboxed `WordSplitter`s to the same variable: ```rust let mut dynamic_opt: Box<Options<dyn WordSplitter>>; dynamic_opt = Box::new(Options::with_splitter(20, NoHyphenation)); dynamic_opt = Box::new(Options::with_splitter(20, Box::new(NoHyphenation))); ``` In both cases, dynamic dispatch would be used at runtime. This was called “proper outer boxing” in #219 and #215. By only boxing the word splitter (so-called “inner boxing”), the outer layer of indirection can be removed: ```rust let mut dynamic_opt: Options<Box<dyn WordSplitter>>; dynamic_opt = Options::with_splitter(20, Box::new(NoHyphenation)); dynamic_opt = Options::with_splitter(20, Box::new(HyphenSplitter)); ``` This also used dynamic dispatch at runtime. Static dispatching was also possible by using a fixed type. Trying to change the word splitter type is a compile time error: ```rust let mut static_opt: Options<NoHyphenation>; static_opt = Options::with_splitter(10, NoHyphenation); static_opt = Options::with_splitter(20, HyphenSplitter); // <- error! ``` In order to add a trait for the `WrapAlgorithm` enum (see #325), we’re now removing the `?Sized` bound on the `WordSplitter` type parameter. This makes the first block above a compile time error and you must now choose upfront between boxed and unboxed word splitters. If you choose a boxed word splitter (second example), then you get dynamic dispatch and can freely change the word splitter at runtime. If you choose an unboxed wordsplitter, you get static dispatch and cannot change the word splitter later. This change seems necessary since we will be adding more type parameters to the `Options` struct: one for the wrapping algorithm used and one for how we find words (splitting by space or by the full Unicode line breaking algorithm). Since both dynamic and static dispatch remains possible, this change should not cause big problems for Textwrap clients.
mgeisler
added a commit
that referenced
this issue
May 1, 2021
In #219, the type parameter for `Options` was relaxed to `?Sized`, which means that `Options<T>` can be a dynamically-sized type by using `dyn WordSplitter` as the type parameter. This allows code to freely assign both boxed and unboxed `WordSplitter`s to the same variable: ```rust let mut dynamic_opt: Box<Options<dyn WordSplitter>>; dynamic_opt = Box::new(Options::with_splitter(20, NoHyphenation)); dynamic_opt = Box::new(Options::with_splitter(20, Box::new(NoHyphenation))); ``` In both cases, dynamic dispatch would be used at runtime. This was called “proper outer boxing” in #219 and #215. By only boxing the word splitter (so-called “inner boxing”), the outer layer of indirection can be removed: ```rust let mut dynamic_opt: Options<Box<dyn WordSplitter>>; dynamic_opt = Options::with_splitter(20, Box::new(NoHyphenation)); dynamic_opt = Options::with_splitter(20, Box::new(HyphenSplitter)); ``` This also used dynamic dispatch at runtime. Static dispatching was also possible by using a fixed type. Trying to change the word splitter type is a compile time error: ```rust let mut static_opt: Options<NoHyphenation>; static_opt = Options::with_splitter(10, NoHyphenation); static_opt = Options::with_splitter(20, HyphenSplitter); // <- error! ``` In order to add a trait for the `WrapAlgorithm` enum (see #325), we’re now removing the `?Sized` bound on the `WordSplitter` type parameter. This makes the first block above a compile time error and you must now choose upfront between boxed and unboxed word splitters. If you choose a boxed word splitter (second example), then you get dynamic dispatch and can freely change the word splitter at runtime. If you choose an unboxed wordsplitter, you get static dispatch and cannot change the word splitter later. This change seems necessary since we will be adding more type parameters to the `Options` struct: one for the wrapping algorithm used and one for how we find words (splitting by space or by the full Unicode line breaking algorithm). Since both dynamic and static dispatch remains possible, this change should not cause big problems for Textwrap clients.
mgeisler
added a commit
that referenced
this issue
May 1, 2021
In #219, the type parameter for `Options` was relaxed to `?Sized`, which means that `Options<T>` can be a dynamically-sized type by using `dyn WordSplitter` as the type parameter. This allows code to freely assign both boxed and unboxed `WordSplitter`s to the same variable: ```rust let mut dynamic_opt: Box<Options<dyn WordSplitter>>; dynamic_opt = Box::new(Options::with_splitter(20, NoHyphenation)); dynamic_opt = Box::new(Options::with_splitter(20, Box::new(NoHyphenation))); ``` In both cases, dynamic dispatch would be used at runtime. This was called “proper outer boxing” in #219 and #215. By only boxing the word splitter (so-called “inner boxing”), the outer layer of indirection can be removed: ```rust let mut dynamic_opt: Options<Box<dyn WordSplitter>>; dynamic_opt = Options::with_splitter(20, Box::new(NoHyphenation)); dynamic_opt = Options::with_splitter(20, Box::new(HyphenSplitter)); ``` This also used dynamic dispatch at runtime. Static dispatching was also possible by using a fixed type. Trying to change the word splitter type is a compile time error: ```rust let mut static_opt: Options<NoHyphenation>; static_opt = Options::with_splitter(10, NoHyphenation); static_opt = Options::with_splitter(20, HyphenSplitter); // <- error! ``` In order to add a trait for the `WrapAlgorithm` enum (see #325), we’re now removing the `?Sized` bound on the `WordSplitter` type parameter. This makes the first block above a compile time error and you must now choose upfront between boxed and unboxed word splitters. If you choose a boxed word splitter (second example), then you get dynamic dispatch and can freely change the word splitter at runtime. If you choose an unboxed wordsplitter, you get static dispatch and cannot change the word splitter later. This change seems necessary since we will be adding more type parameters to the `Options` struct: one for the wrapping algorithm used and one for how we find words (splitting by space or by the full Unicode line breaking algorithm). Since both dynamic and static dispatch remains possible, this change should not fundamentally change the expressive power of the library.
mgeisler
changed the title
Make trait for
Introduce a trait for May 16, 2021
WrapAlgorithm
WrapAlgorithm
mgeisler
added a commit
that referenced
this issue
May 16, 2021
I plan to introduce a trait for the wrap algorithms (#325) and this aligns better with such a trait. The reason is that a trait method cannot have generic parameters, such as a `F: Fn(usize) -> usize` parameter.
mgeisler
added a commit
that referenced
this issue
May 16, 2021
I plan to introduce a trait for the wrap algorithms (#325) and this aligns better with such a trait. The reason is that a trait method cannot have generic parameters, such as a `F: Fn(usize) -> usize` parameter.
mgeisler
added a commit
that referenced
this issue
May 16, 2021
This introduces a `textwrap::wrap_algorithms` module where the `wrap_first_fit` and `wrap_optimal_fit` functions now live. A new `WrapAlgorithm` trait replaces the old enum. This allows for arbitrary wrapping algorithms to be plugged into the library. We should also be able to change the return type from `Vec<&[Word]>` to `Iterator<Item = Word>` and thus implement streaming wrapping for the first-fit in the future. Fixes #325.
mgeisler
added a commit
that referenced
this issue
May 16, 2021
This introduces a `textwrap::wrap_algorithms` module where the `wrap_first_fit` and `wrap_optimal_fit` functions now live. A new `WrapAlgorithm` trait replaces the old enum. This allows for arbitrary wrapping algorithms to be plugged into the library. We should also be able to change the return type from `Vec<&[Word]>` to `Iterator<Item = Word>` and thus implement streaming wrapping for the first-fit in the future. Fixes #325.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The
WrapAlgorithm
enum should be turned into a trait. This will allow us to.collect::<Vec<_>>()
in our procesing pipeline. We do this today since the different wrapping algorithms return differentIterator
types.The text was updated successfully, but these errors were encountered: