You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: compiler.rs
    path of file: ./repos/doukutsu-rs/src/game/scripting/tsc
    
    the code of the file until where you have to start completion: use std::collections::HashMap;
use std::iter::Peekable;
use std::str::FromStr;

use itertools::Itertools;

use crate::framework::error::GameError::ParseError;
use crate::framework::error::GameResult;
use crate::game::scripting::tsc::bytecode_utils::{put_string, put_varint};
use crate::g
    
    pub fn compile(data: &[u8], strict: bool, encoding: TextScriptEncoding) -> GameResult<CreditScript> {
        let mut labels = HashMap::new();
        let mut bytecode = Vec::new();
        let mut iter = data.iter().copied().peekable();

        while let Some(chr) = iter.next() {
            match chr {
                b'/' => {
                    put_varint(CreditOpCode::StopCredits as i32, &mut bytecode);
                }
                b'[' => {
                    let mut char_buf = Vec::new();

                    while let Some(&chr) = iter.peek() {
                        if chr == b']' {
                            iter.next();
                            break;
                        }

                        char_buf.push(chr);
                        iter.next();
                    }

                    if let Ok(cast_tile) = read_number(&mut iter) {
                        put_varint(CreditOpCode::PushLine as i32, &mut bytecode);
                        put_varint((cast_tile as u16) as i32, &mut bytecode);
                        put_string(&mut char_buf, &mut bytecode, encoding);
                    }
                }
                b'-' => {
                    let ticks = read_number(&mut iter)? as u16;

                    put_varint(CreditOpCode::Wait as i32, &mut bytecode);
                    put_varint(ticks as i32, &mut bytecode);
                }
                b'+' => {
                    let offset = read_number(&mut iter)?;

                    put_varint(CreditOpCode::ChangeXOffset as i32, &mut bytecode);
                    put_varint(offset, &mut bytecode);
                }
                b'!' => {
                    let music = read_number(&mut iter)? as u16;

                    put_varint(CreditOpCode::ChangeMusic as i32, &mut bytecode);
                    put_varint(music as i32, &mut bytecode);
                }
                b'~' => {
                    put_varint(CreditOpCode::FadeMusic as i32, &mut bytecode);
                }
                b'l' => {
                    let label = read_number(&mut iter)? as u16;
                    let pos = bytecode.len() as u32;

                    labels.insert(label, pos);
                }
                b'j' => {
                    let label = read_number(&mut iter)? as u16;

                    put_varint(CreditOpCode::JumpLabel as i32, &mut bytecode);
                    put_varint(label as i32, &mut bytecode);
                }
                b'f' => {
                    let flag = read_number(&mut iter)? as u16;
                    if strict {
                        expect_char(b':', &mut iter)?;
                    } else {
                        iter.next().ok_or_else(|| ParseError("Script unexpectedly ended.".to_owned()))?;
                    }
                    let label = read_number(&mut iter)? as u16;

                    put_varint(CreditOpCode::JumpFlag as i32, &mut bytecode);
                    put_varint(flag as i32, &mut bytecode);
                    put_varint(label as i32, &mut bytecode);
                }
                b'p' => {
                    iter.next(); // idfk what's that for, in cs+ Credits.tsc it's '2'.

                    if strict {
                        expect_char(b':', &mut iter)?;
                    } else {
                        iter.next().ok_or_else(|| ParseError("Script unexpectedly ended.".to_owned()))?;
                    }

                    let label = read_number(&mut iter)? as u16;

                    put_varint(CreditOpCode::JumpPlayer2 as i32, &mut bytecode);
                    put_varint(label as i32, &mut bytecode);
                }
                _ => (),
            }
        }

        Ok(CreditScript { labels, bytecode })
    }