noak 0.6.3

A library for reading and writing java class files
Documentation
use std::fmt;
use std::marker::PhantomData;

use crate::error::*;
use crate::header::AccessFlags;
use crate::writer::{
    attributes::{AttributeWriter, AttributeWriterState},
    class, cpool,
    encoding::*,
    ClassWriter,
};

pub struct MethodWriter<State: MethodWriterState::State> {
    class_writer: ClassWriter<class::ClassWriterState::Methods>,
    _marker: PhantomData<State>,
}

impl MethodWriter<MethodWriterState::AccessFlags> {
    pub fn access_flags(mut self, flags: AccessFlags) -> Result<MethodWriter<MethodWriterState::Name>, EncodeError> {
        self.class_writer.encoder().write(flags)?;
        Ok(MethodWriter {
            class_writer: self.class_writer,
            _marker: PhantomData,
        })
    }
}

impl MethodWriter<MethodWriterState::Name> {
    pub fn name<I>(mut self, name: I) -> Result<MethodWriter<MethodWriterState::Descriptor>, EncodeError>
    where
        I: cpool::Insertable<cpool::Utf8>,
    {
        let index = name.insert(&mut self.class_writer)?;
        self.class_writer.encoder().write(index)?;
        Ok(MethodWriter {
            class_writer: self.class_writer,
            _marker: PhantomData,
        })
    }
}

impl MethodWriter<MethodWriterState::Descriptor> {
    pub fn descriptor<I>(mut self, descriptor: I) -> Result<MethodWriter<MethodWriterState::Attributes>, EncodeError>
    where
        I: cpool::Insertable<cpool::Utf8>,
    {
        let index = descriptor.insert(&mut self.class_writer)?;
        self.class_writer.encoder().write(index)?;
        Ok(MethodWriter {
            class_writer: self.class_writer,
            _marker: PhantomData,
        })
    }
}

impl MethodWriter<MethodWriterState::Attributes> {
    pub fn attributes<F>(mut self, f: F) -> Result<MethodWriter<MethodWriterState::End>, EncodeError>
    where
        F: FnOnce(
            &mut ManyWriter<
                AttributeWriter<ClassWriter<class::ClassWriterState::Methods>, AttributeWriterState::Start>,
                u16,
            >,
        ) -> Result<(), EncodeError>,
    {
        let mut builder = ManyWriter::new(self.class_writer)?;
        f(&mut builder)?;
        self.class_writer = builder.finish()?;

        Ok(MethodWriter {
            class_writer: self.class_writer,
            _marker: PhantomData,
        })
    }
}

impl WriteAssembler for MethodWriter<MethodWriterState::AccessFlags> {
    type Context = ClassWriter<class::ClassWriterState::Methods>;

    fn new(class_writer: Self::Context) -> Result<Self, EncodeError> {
        Ok(MethodWriter {
            class_writer,
            _marker: PhantomData,
        })
    }
}

impl WriteDisassembler for MethodWriter<MethodWriterState::End> {
    type Context = ClassWriter<class::ClassWriterState::Methods>;

    fn finish(self) -> Result<Self::Context, EncodeError> {
        Ok(self.class_writer)
    }
}

impl<State: MethodWriterState::State> fmt::Debug for MethodWriter<State> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("MethodWriter").finish()
    }
}

enc_state!(pub mod MethodWriterState: AccessFlags, Name, Descriptor, Attributes, End);