4

I am a beginner at Rust. I am trying to use the BitVec library to represent an array of bits. I started playing with it by appending sequences of 0s or 1s, but I am having some problems at doing so. When I append a sequence of x 0s then a sequence of y 1s, what it does instead is to append x+y zeroes. Note that if I just append 1s without appending 0s before, it works. Here is my code:

extern crate bit_vec;
use bit_vec::BitVec;

fn main(){
    let mut bits = BitVec::new();   // creates an empty array of bits
    append_zero(&mut bits);
    append_one(&mut bits);
    append_zero(&mut bits);
    append_one(&mut bits);
    append_one(&mut bits);          // everything works perfectly till here
    append_n_ones(&mut bits, 2);    // this works
    append_n_zeroes(&mut bits, 3);  // this too
    append_n_ones(&mut bits, 2);    // this appends 2 zeroes instead!
    println!("{:?}", bits);
}

fn append_zero(vector: &mut BitVec) {
    vector.push(false);
}

fn append_one(vector: &mut BitVec) {
    vector.push(true);
}

fn append_n_zeroes(vector: &mut BitVec, n: usize) {
    let mut to_append = BitVec::from_elem(n, false);  // creates a BitVec with n 0s
    println!("trying to append: {:?}", to_append);
    vector.append(&mut to_append);
}

fn append_n_ones(vector: &mut BitVec, n: usize) {
    let mut to_append = BitVec::from_elem(n, true);  // creates a BitVec with n 1s
    println!("trying to append: {:?}", to_append);
    vector.append(&mut to_append);
}

This is the output:

trying to append: 11
trying to append: 000
trying to append: 11
010111100000

Note that the last line should have been 010111100011. Moreover, before appending it, 11 is correctly printed. But then it appends 00.

I am using this website to test my Rust code, but locally it has the same problems. I tried to look at the code for the BitVec library but it is too advanced for my level of Rust at the moment.

Xito Dev
  • 55
  • 5
  • 2
    [Issue 63: BitVec::append fails silently](https://github.com/contain-rs/bit-vec/issues/63) apparently `append` can silently corrupt the vector. – Masklinn Oct 03 '20 at 13:45
  • @Masklinn thanks! it seems that I will have to do it without this lib, as they commented on making a PR to fix the error but it doesn't seem that anybody commited anything yet. – Xito Dev Oct 03 '20 at 14:00
  • 1
    There are actually two PRs, but the crate doesn't seem to be much maintained. Also interestingly using `extend` works fine, possibly because it skipped some of the optimisations. I got the idea because when looking for the documentation I checked the wrong crate (`bitvec` whose author commented here) and there `append` just calls `extend`. You can imagine my confusion when that cleared away the issue despite there being no reason to given the code I was looking at. – Masklinn Oct 03 '20 at 15:38
  • @Masklinn can you write this as an answer? I would accept it. If you can explain how I can use `extend`, I am trying but it asks me for an iterator. – Xito Dev Oct 04 '20 at 09:32
  • ah ok, I just have to use `.iter()` on my BitVec object (`to_append`) – Xito Dev Oct 04 '20 at 09:43

1 Answers1

7

The bit_vec crate, while old and popular, is in maintenance-only. I am the author of a replacement, bitvec, which behaves as you desire and (in my opinion) is a better product.

You can use your code as-written by replacing bit_vec with bitvec and BitVec::from_elem with BitVec::<Lsb0, usize>::repeat. Unfortunately, bitvec is not available on the Rust playground, so I can't show you directly.

myrrlyn
  • 136
  • 4
  • 4