//! A WebAssembly encoder.
//!
//! The main builder is the [`Module`]. You can build a section with a
//! section-specific builder, like [`TypeSection`] or [`ImportSection`], and
//! then add it to the module with [`Module::section`]. When you are finished
//! building the module, call either [`Module::as_slice`] or [`Module::finish`]
//! to get the encoded bytes. The former gives a shared reference to the
//! underlying bytes as a slice, while the latter gives you ownership of them as
//! a vector.
//!
//! # Example
//!
//! If we wanted to build this module:
//!
//! ```wasm
//! (module
//!   (type (func (param i32 i32) (result i32)))
//!   (func (type 0)
//!     local.get 0
//!     local.get 1
//!     i32.add)
//!   (export "f" (func 0)))
//! ```
//!
//! then we would do this:
//!
//! ```
//! use wasm_encoder::{
//!     CodeSection, ExportKind, ExportSection, Function, FunctionSection, Instruction,
//!     Module, TypeSection, ValType,
//! };
//!
//! let mut module = Module::new();
//!
//! // Encode the type section.
//! let mut types = TypeSection::new();
//! let params = vec![ValType::I32, ValType::I32];
//! let results = vec![ValType::I32];
//! types.ty().function(params, results);
//! module.section(&types);
//!
//! // Encode the function section.
//! let mut functions = FunctionSection::new();
//! let type_index = 0;
//! functions.function(type_index);
//! module.section(&functions);
//!
//! // Encode the export section.
//! let mut exports = ExportSection::new();
//! exports.export("f", ExportKind::Func, 0);
//! module.section(&exports);
//!
//! // Encode the code section.
//! let mut codes = CodeSection::new();
//! let locals = vec![];
//! let mut f = Function::new(locals);
//! f.instruction(&Instruction::LocalGet(0));
//! f.instruction(&Instruction::LocalGet(1));
//! f.instruction(&Instruction::I32Add);
//! f.instruction(&Instruction::End);
//! codes.function(&f);
//! module.section(&codes);
//!
//! // Extract the encoded Wasm bytes for this module.
//! let wasm_bytes = module.finish();
//!
//! // We generated a valid Wasm module!
//! assert!(wasmparser::validate(&wasm_bytes).is_ok());
//! ```

#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![deny(missing_docs, missing_debug_implementations)]

#[cfg(feature = "component-model")]
mod component;
mod core;
mod raw;
#[cfg(feature = "wasmparser")]
pub mod reencode;

#[cfg(feature = "component-model")]
pub use self::component::*;
pub use self::core::*;
pub use self::raw::*;

/// Implemented by types that can be encoded into a byte sink.
pub trait Encode {
    /// Encode the type into the given byte sink.
    fn encode(&self, sink: &mut Vec<u8>);
}

impl<T: Encode + ?Sized> Encode for &'_ T {
    fn encode(&self, sink: &mut Vec<u8>) {
        T::encode(self, sink)
    }
}

impl<T: Encode> Encode for [T] {
    fn encode(&self, sink: &mut Vec<u8>) {
        self.len().encode(sink);
        for item in self {
            item.encode(sink);
        }
    }
}

impl Encode for [u8] {
    fn encode(&self, sink: &mut Vec<u8>) {
        self.len().encode(sink);
        sink.extend(self);
    }
}

impl Encode for str {
    fn encode(&self, sink: &mut Vec<u8>) {
        self.len().encode(sink);
        sink.extend_from_slice(self.as_bytes());
    }
}

impl Encode for usize {
    fn encode(&self, sink: &mut Vec<u8>) {
        assert!(*self <= u32::max_value() as usize);
        (*self as u32).encode(sink)
    }
}

impl Encode for u32 {
    fn encode(&self, sink: &mut Vec<u8>) {
        leb128::write::unsigned(sink, (*self).into()).unwrap();
    }
}

impl Encode for i32 {
    fn encode(&self, sink: &mut Vec<u8>) {
        leb128::write::signed(sink, (*self).into()).unwrap();
    }
}

impl Encode for u64 {
    fn encode(&self, sink: &mut Vec<u8>) {
        leb128::write::unsigned(sink, *self).unwrap();
    }
}

impl Encode for i64 {
    fn encode(&self, sink: &mut Vec<u8>) {
        leb128::write::signed(sink, *self).unwrap();
    }
}

impl Encode for f32 {
    fn encode(&self, sink: &mut Vec<u8>) {
        let bits = self.to_bits();
        sink.extend(bits.to_le_bytes())
    }
}

impl Encode for f64 {
    fn encode(&self, sink: &mut Vec<u8>) {
        let bits = self.to_bits();
        sink.extend(bits.to_le_bytes())
    }
}

fn encode_vec<T, V>(elements: V, sink: &mut Vec<u8>)
where
    T: Encode,
    V: IntoIterator<Item = T>,
    V::IntoIter: ExactSizeIterator,
{
    let elements = elements.into_iter();
    u32::try_from(elements.len()).unwrap().encode(sink);
    for x in elements {
        x.encode(sink);
    }
}

impl<T> Encode for Option<T>
where
    T: Encode,
{
    fn encode(&self, sink: &mut Vec<u8>) {
        match self {
            Some(v) => {
                sink.push(0x01);
                v.encode(sink);
            }
            None => sink.push(0x00),
        }
    }
}

fn encoding_size(n: u32) -> usize {
    let mut buf = [0u8; 5];
    leb128::write::unsigned(&mut &mut buf[..], n.into()).unwrap()
}

fn encode_section(sink: &mut Vec<u8>, count: u32, bytes: &[u8]) {
    (encoding_size(count) + bytes.len()).encode(sink);
    count.encode(sink);
    sink.extend(bytes);
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn it_encodes_an_empty_module() {
        let bytes = Module::new().finish();
        assert_eq!(bytes, [0x00, b'a', b's', b'm', 0x01, 0x00, 0x00, 0x00]);
    }

    #[test]
    fn it_encodes_an_empty_component() {
        let bytes = Component::new().finish();
        assert_eq!(bytes, [0x00, b'a', b's', b'm', 0x0d, 0x00, 0x01, 0x00]);
    }
}
