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
Use u8
and [u8]
, not char
and str
for printing methods on Console
#161
Conversation
`Console`’s printing functions don’t work with Unicode strings or characters, so it doesn’t make sense to use the `char` (Unicode scalar value) and `str` (UTF-8 string) types for printing.
The ergonomic impact seems much higher to me, but yeah, this is a problem. I absolutely agree that we should allow What do you think of accepting something like (we'd have to define a different trait because the types and the That conversion would have a performance hit, but you'd get a runtime error and you could always make it fast by using the ASCII types directly. I.e. easy for people getting started but not costing folks who know what they're doing. |
Since pub trait PrintString {
fn print(&self, con: &mut Console);
}
impl PrintString for [u8] {
fn print(&self, con: &mut Console) {
// Print ASCII using the ffi
}
}
impl<'a> PrintString for &'a str {
fn print(&self, con: &mut Console) {
// Print Unicode using the ffi
}
}
impl PrintString for String {
fn print(&self, con: &mut Console) {
// Print Unicode using the ffi
}
} Using this, the definition for the actual print function would look something like this: fn print<T>(&mut self, x: i32, y: i32, text: &T) where T: PrintString {
assert!(x >= 0 && y >= 0);
text.print(self);
} This could also be repeated for |
@tomassedovic Yeah, I was just thinking about doing that. Potentially (perhaps later in a different PR, though) the One question, though: the ASCII control characters display differently in libtcod’s character set. These characters could easily be supported using @Gustorn I did try to use the |
@P1start Does |
@Gustorn Are Unicode fonts available for libtcod? I was under the impression that only 256-character terminal.png-like fonts were supported. And I’m pretty sure they’re UTF-32 because the C API expects Also, I just realised that a static-dispatch-based API ( |
Here's a forum topic about an (apparently) full Unicode bitmap font. As for Object safety is actually a really good point, one which I haven't considered. To be completely honest, I haven't really seen a use-case for using trait objects, so object safety is doesn't seem a terribly big deal to me: the only function where Console types are actually interchangeable is |
@Gustorn Looks like that ‘only’ supports the basic multilingual plane, but I now see that you can indeed support more than just 256 characters. I guess I now know how I was using the One of the first things I wrote with tcod involved using trait Draw {
fn draw(&self, &mut Console);
} And then there was going to be a |
Yeah, unfortunaly that is a valid example, even though I would argue that drawing on I still think that using root.print(args...);
// Would become
console::print(root, args...); |
So here's some testing I've done with object safety, and I'm happy to say, we can actually do the generic print and have |
I'm sorry, but I've had little time to participate today and I'll be completely off for the next few days. If you come up with something that doesn't require the I'll be back on Monday so if it doesn't come in by then, I'll read through this thread again and get this fixed one way or another. Thanks both of you. |
Proposing to close this since #163 was merged. |
Agreed, the unicode concerns should be addressed by #163. Note that we still don't use Thanks @P1start for starting this! If you feel we should re-open this, feel free to comment here. |
I'll reopen this since I did a bit of research regarding the literals. After a bit of experimentation I'm not sure if we should accept ASCII literals, and here's why. With the current implementation we choose the printing function based on Rust's Now the current runtime dispatch could be combined with a custom trait, but I'm not sure if introducing arbitrary rules for the different string types is such a good idea. Let's say we have the trait
This is probably close to the behaviour people would expect: since I can probably implement it in a way that still accepts user-defined string types, provided they implement |
Console
’s printing methods don’t work with Unicode strings or characters, so it doesn’t make sense to use thechar
(Unicode scalar value) andstr
(UTF-8 string) types. This changes these methods to useu8
and[u8]
instead. The ergonomic impact of this is minimal (although it breaks just about all code, unfortunately), due to the existence of byte string and character literals (b"foo"
andb'c'
), and additionally, this makes it possible to specify special characters directly inside byte strings (e.g., printingb"90\xf8"
(0xf8
ischars::GRADE
) now displays90°
, but previously displayed90├©
due to the fact that strings are UTF-8).