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: initialize.rs
    path of file: ./repos/ferrocarril/mruby/src/extn/core/regexp
    
    the code of the file until where you have to start completion: //! [`Regexp::new`](https://ruby-doc.org/core-2.6.3/Regexp.html#method-c-new)
//! and
//! [`Regexp::compile`](https://ruby-doc.org/core-2.6.3/Regexp.html#method-c-compile)

use std::mem;

use crate::convert::RustBackedValue;
use crate::extn::core::regexp::enc::{self, Encoding};
use crate::extn::core::regexp::opts::{self, Options};
use crate::extn::core::regexp::Regexp;
use crate::sys;
use crate::value::Value;
use crate::warn::MrbWarn;
use crate::Mrb;

#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub enum Error {
    Fatal,
    NoImplicitConversionToString,
    Syntax,
    Unicode,
}

#[derive(Debug)]
pub struct Args {
    pub pattern: Value,
    pub options: Option<Options>,
    pub encoding: Option<Encoding>,
}

impl Args {
    const ARGSPEC: &'static [u8] = b"o|o?o?\0";

    pub unsafe fn extract(interp: &Mrb) -> Result<Self, Error> {
        let mut pattern = <mem::MaybeUninit<sys::mrb_value>>::uninit();
        let mut opts = <mem::MaybeUninit<sys::mrb_value>>::uninit();
        let mut has_opts = <mem::MaybeUninit<sys::mrb_bool>>::uninit();
        let mut enc = <mem::MaybeUninit<sys::mrb_value>>::uninit();
        let mut has_enc = <mem::MaybeUninit<sys::mrb_bool>>::uninit();
        sys::mrb_get_args(
            interp.borrow().mrb,
            Self::ARGSPEC.as_ptr() as *const i8,
            pattern.as_mut_ptr(),
            opts.as_mut_ptr(),
            has_opts.as_mut_ptr(),
            enc.as_mut_ptr(),
            has_enc.as_mut_ptr(),
        );
        let pattern = pattern.assume_init();
        let has_opts = has_opts.assume_init() != 0;
        let has_enc = has_enc.assume_init() != 0;
        let pattern = Value::new(&interp, pattern);
        let options = if has_opts {
            Some(opts::parse(&Value::new(interp, opts.assume_init())))
        } else {
            None
        };
        let encoding = if has_enc {
            let encoding = Value::new(interp, enc.assume_init());
            match enc::parse(&encoding) {
                Ok(encoding) =>
    
    pub unsafe fn extract(interp: &Mrb) -> Result<Self, Error> {
        let mut pattern = <mem::MaybeUninit<sys::mrb_value>>::uninit();
        let mut opts = <mem::MaybeUninit<sys::mrb_value>>::uninit();
        let mut has_opts = <mem::MaybeUninit<sys::mrb_bool>>::uninit();
        let mut enc = <mem::MaybeUninit<sys::mrb_value>>::uninit();
        let mut has_enc = <mem::MaybeUninit<sys::mrb_bool>>::uninit();
        sys::mrb_get_args(
            interp.borrow().mrb,
            Self::ARGSPEC.as_ptr() as *const i8,
            pattern.as_mut_ptr(),
            opts.as_mut_ptr(),
            has_opts.as_mut_ptr(),
            enc.as_mut_ptr(),
            has_enc.as_mut_ptr(),
        );
        let pattern = pattern.assume_init();
        let has_opts = has_opts.assume_init() != 0;
        let has_enc = has_enc.assume_init() != 0;
        let pattern = Value::new(&interp, pattern);
        let options = if has_opts {
            Some(opts::parse(&Value::new(interp, opts.assume_init())))
        } else {
            None
        };
        let encoding = if has_enc {
            let encoding = Value::new(interp, enc.assume_init());
            match enc::parse(&encoding) {
                Ok(encoding) => Some(encoding),
                Err(enc::Error::InvalidEncoding) => {
                    let warning = format!("encoding option is ignored -- {}", encoding.to_s());
                    interp.warn(warning.as_str()).map_err(|_| Error::Fatal)?;
                    None
                }
            }
        } else if has_opts {
            let encoding = Value::new(interp, opts.assume_init());
            match enc::parse(&encoding) {
                Ok(encoding) => Some(encoding),
                Err(enc::Error::InvalidEncoding) => {
                    let warning = format!("encoding option is ignored -- {}", encoding.to_s());
                    interp.warn(warning.as_str()).map_err(|_| Error::Fatal)?;
                    None
                }
            }
        } else {
            None
        };

        Ok(Self {
            pattern,
            options,
            encoding,
        })
    }