forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy path122823.rs
69 lines (57 loc) · 1.65 KB
/
122823.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
//@ known-bug: #122823
//@ compile-flags: -Copt-level=0
// ignore-tidy-linelength
use std::vec::Vec;
use std::iter::Peekable;
pub fn main() {
let packet = decode(vec![1,0,1,0]);
}
pub fn decode(bitstream: Vec<u64>) -> Packet {
let mut bitstream_itr = bitstream.into_iter().peekable();
return match decode_packet(&mut bitstream_itr) {
Some(p) => p,
None => panic!("expected outer packet"),
}
}
pub fn decode_packets<I: Iterator<Item = u64>>(itr: &mut Peekable<I>) -> Vec<Packet> {
let mut res = Vec::new();
loop {
match decode_packet(itr) {
Some(p) => { res.push(p); },
None => break
}
}
return res;
}
pub fn decode_packet<I: Iterator<Item = u64>>(itr: &mut Peekable<I>) -> Option<Packet> {
// get version digits
let version = extend_number(0, itr, 3)?;
let type_id = extend_number(0, itr, 3)?;
return operator_packet(version, type_id, itr);
}
pub fn operator_packet<I: Iterator<Item = u64>>(version: u64, type_id: u64, itr: &mut Peekable<I>) -> Option<Packet> {
let p = OperatorPacket {
version: version,
type_id: type_id,
packets: decode_packets(&mut itr.take(0).peekable()),
};
return Some(Packet::Operator(p));
}
pub fn extend_number<I: Iterator<Item = u64>>(num: u64, itr: &mut Peekable<I>, take: u64) -> Option<u64> {
let mut value = num;
for _ in 0..take {
value *= 2;
value += itr.next()?;
}
return Some(value);
}
#[derive(Debug)]
pub enum Packet {
Operator(OperatorPacket),
}
#[derive(Debug)]
pub struct OperatorPacket {
version: u64,
type_id: u64,
packets: Vec<Packet>
}