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: messages.rs
    path of file: ./repos/wormhole/solana/modules/nft_bridge/program/src
    
    the code of the file until where you have to start completion: use crate::types::{
    Address,
    ChainID,
};
use bridge::{
    vaa::{
        DeserializePayload,
        SerializePayload,
    },
    DeserializeGovernancePayload,
    SerializeGovernancePayload,
};
use byteorder::{
    BigEndian,
    ReadBytesExt,
    WriteBytesExt,
};
use primitive_types::U256;
use solana_program::{
    program_error::ProgramError::InvalidAccountData,
    pubkey::Pubkey,
};
use solitaire::SolitaireError;
use std::{
    cmp,
    io::{
        Cursor,
        Read,
        Write,
    },
};

pub const MODULE: &str = "NFTBridge";

#[derive(PartialEq, Debug, Clone)]
pub struct PayloadTransfer {
    // Address of the token. Left-zero-padded if shorter than 32 bytes
    pub token_address: Address,
    // Chain ID of the token
    pub token_chain: ChainID,
    // Symbol of the token
    pub symbol: String,
    // Name of the token
    pub name: String,
    // TokenID of the token (big-endian uint256)
    pub token_id: U256,
    // URI of the token metadata
    pub uri: String,
    // Address of the recipient. Left-zero-padded if shorter than 32 bytes
    pub to: Address,
    // Chain ID of the recipient
    pub to_chain: ChainID,
}

impl DeserializePayload for PayloadTransfer {
    fn deserialize(buf: &mut &[u8]) -> Result<Self, SolitaireError> {
        use bstr::ByteSlice;
        let mut v = Cursor::new(buf);

        if v.read_u8()? != 1 {
            return Err(SolitaireError::Custom(0));
        };

        let mut token_address = Address::default();
        v.read_exact(&mut token_address)?;

        let token_chain = v.read_u16::<BigEndian>()?;

        // We may receive invalid UTF-8 over the bridge, especially if truncated. To compensate for
        // this we rely on the bstr libraries ability to parse invalid UTF-8, and strip out the
        // "Invalid Unicode Codepoint" (FFFD) characters. This becomes the canonical representation
        // on Solana.
        let mut symbol_data = vec![0u8; 32];
        v.read_ex
    
    fn deserialize(buf: &mut &[u8]) -> Result<Self, SolitaireError> {
        use bstr::ByteSlice;
        let mut v = Cursor::new(buf);

        if v.read_u8()? != 1 {
            return Err(SolitaireError::Custom(0));
        };

        let mut token_address = Address::default();
        v.read_exact(&mut token_address)?;

        let token_chain = v.read_u16::<BigEndian>()?;

        // We may receive invalid UTF-8 over the bridge, especially if truncated. To compensate for
        // this we rely on the bstr libraries ability to parse invalid UTF-8, and strip out the
        // "Invalid Unicode Codepoint" (FFFD) characters. This becomes the canonical representation
        // on Solana.
        let mut symbol_data = vec![0u8; 32];
        v.read_exact(&mut symbol_data)?;
        symbol_data.retain(|&c| c != 0);
        let mut symbol: Vec<char> = symbol_data.chars().collect();
        symbol.retain(|&c| c != '\u{FFFD}');
        let symbol: String = symbol.iter().collect();

        let mut name_data = vec![0u8; 32];
        v.read_exact(&mut name_data)?;
        name_data.retain(|&c| c != 0);
        let mut name: Vec<char> = name_data.chars().collect();
        name.retain(|&c| c != '\u{FFFD}');
        let name: String = name.iter().collect();

        let mut id_data: [u8; 32] = [0; 32];
        v.read_exact(&mut id_data)?;
        let token_id = U256::from_big_endian(&id_data);

        let uri_len = v.read_u8()?;
        let mut uri_bytes = vec![0u8; uri_len as usize];
        v.read_exact(uri_bytes.as_mut_slice())?;
        let uri = String::from_utf8(uri_bytes).unwrap();

        let mut to = Address::default();
        v.read_exact(&mut to)?;

        let to_chain = v.read_u16::<BigEndian>()?;

        if v.position() != v.into_inner().len() as u64 {
            return Err(InvalidAccountData.into());
        }

        Ok(PayloadTransfer {
            token_address,
            token_chain,
            to,
            to_chain,
            symbol,
            name,
            token_id,
            uri,
        })
    }