crossterm-rs / crossterm

Cross platform terminal library rust
MIT License
3.2k stars 276 forks source link

expose attributes bits #467

Closed aeosynth closed 3 years ago

aeosynth commented 4 years ago

i want to diff two Attributes to then find the minimum attribute sets needed. Currently Attributes doesn't support subtraction or expose the internal bitfield. In my project I'm storing both a copy of the Attributes bitfield and the changed Attribute.

TimonPost commented 4 years ago

Hi there, Attributes is a bitset of Attribute types, it allows you do use bitwise operations, have you checked those out?

https://docs.rs/crossterm/0.17.7/crossterm/style/struct.Attributes.html https://github.com/crossterm-rs/crossterm/blob/master/src/style/attributes.rs

Note that Attributes is not the same as Attribute

aeosynth commented 4 years ago

Given two Attributes bitsets with one bit difference, how do I find the changed bit, without checking each bit individually with Attributes::has(Attribute)? Using xor doesn't help, it will give me a new bitset but I still have to check each bit.

sigmaSd commented 4 years ago

I think that xor then iterating bit by bit looks like a good solution. The iterating part can be implemented on the library level by implementing iterator on Attributes (Item=Attribute).

aeosynth commented 4 years ago

The problem with that is it still doesn't tell you the 'direction' of the changed bit, just that it is changed. So you have to xor, find the changed bit, then check the status of that bit in the original. This could be a single subtract operation.

sigmaSd commented 4 years ago

This is what I'm thinking https://github.com/sigmaSd/crossterm/blob/impl_Iterator_for_Attributes/src/style/attributes.rs You can use this example to test

fn main() {
    let mut a = crossterm::style::Attributes::default();
    use crossterm::style::Attribute::*;
    a.set(Fraktur);
    a.set(Bold);
    let mut b = crossterm::style::Attributes::default();
    b.set(Bold);
    assert!((a ^ b).next() == Some(Fraktur));
}
sigmaSd commented 4 years ago

SideNote: I noticed that this https://docs.rs/crossterm/0.17.7/src/crossterm/style/types/attribute.rs.html#162 can panic with overflow if this enum https://docs.rs/crossterm/0.17.7/src/crossterm/style/types/attribute.rs.html#91 has more than 31 elements (which may or may not be a possibility in the future)

TimonPost commented 4 years ago

Let me know if this still doesn't answer your question.

TimonPost commented 3 years ago

Closing this issue for inactivity reasons. Feel free to open or respond to the provided comments.