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: loader.rs
    path of file: ./repos/panopticon/core/src
    
    the code of the file until where you have to start completion: /*
 * Panopticon - A libre disassembler
 * Copyright (C) 2015, 2016  Panopticon authors
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

//! Loader for 32 and 64-bit ELF, PE, and Mach-o files.


use crate::{Bound, CallTarget, Layer, Program, Project, Region, Result, Rvalue};
use goblin::{self, Hint, archive, elf, mach, pe};
use goblin::elf::program_header;

use panopticon_graph_algos::MutableGraphTrait;
use std::fs::File;
use std::io::{Cursor, Read, Seek, SeekFrom};
use std::path::Path;
use uuid::Uuid;

/// CPU the binary file is intended for.
#[derive(Clone,Copy,Debug)]
pub enum Machine {
    /// 8-bit AVR
    Avr,
    /// AMD64
    Amd64,
    /// Intel x86
    Ia32,
}

/// Parses a non-fat Mach-o binary from `bytes` at `offset` and creates a `Project` from it. Returns the `Project` instance and
/// the CPU its intended for.
pub fn load_mach(bytes: &[u8], offset: usize, name: String) -> Result<(Project, Machine)> {
    let binary = mach::MachO::parse(&bytes, offset)?;
    debug!("mach: {:#?}", &binary);
    let mut base = 0x0;
    let cputype = binary.header.cputype;
    let (machine, mut reg) = match cputype {
        mach::cputype::CPU_TYPE_X86 => {
            let reg = Region::undefined("RAM".to_string(), 0x1_0000_0000);
            (Machine::Ia32, reg)
        }
        mach::cputype::CPU_TYPE_X86_64 => {
            let reg = Region::undefined("RAM".to_string(), 0xFFFF_FFFF_FFFF_FFFF);
            (Machine::Amd64, reg)
        }
        machine => {
            return Err(
                format!(
                    "Unsupported machine ({:#x}): {}",
                    machine,
                    mach::cputype::cpu_type_to_str(machine)
                )
                        .into()
            )
        }
    };

    for segment in &*binary.segments {
        let offset = segment.fileoff as usize;
     
    
fn load_pe(bytes: &[u8], name: String) -> Result<(Project, Machine)> {
    let pe = pe::PE::parse(&bytes)?;
    debug!("pe: {:#?}", &pe);
    let image_base = pe.image_base as u64;
    let mut ram = Region::undefined("RAM".to_string(), 0x100000000);
    for section in &pe.sections {
        let name = String::from_utf8_lossy(&section.name);
        debug!("section: {}", name);
        let virtual_address = section.virtual_address as u64;
        let offset = section.pointer_to_raw_data as usize;
        let (layer, size) = {
            let vsize = section.virtual_size as u64;
            let size = section.size_of_raw_data as usize;
            if size > 0 {
                if offset + size >= bytes.len() {
                    debug!(
                        "bad section pointer: {:#x} + {:#x} >= {:#x}",
                        offset,
                        size,
                        bytes.len()
                    );
                    (Layer::undefined(0), 0)
                } else {
                    debug!("mapped '{}': {:?}", name, offset..offset + size);
                    (Layer::wrap(bytes[offset..offset + size].to_vec()), size as u64)
                }
            } else {
                debug!("bss '{}'", name);
                (Layer::undefined(vsize), vsize)
            }
        };
        let begin = image_base + virtual_address;
        let end = image_base + virtual_address + size as u64;
        let bound = Bound::new(begin, end);
        debug!("bound: {:?}", &bound);
        if !ram.cover(bound, layer) {
            debug!("bad cover");
            return Err(format!("Cannot cover bound: {:?}", Bound::new(begin, end)).into());
        }
    }
    let entry = (pe.image_base + pe.entry) as u64;
    debug!("entry: {:#x}", entry);
    let mut prog = Program::new("prog0");
    let mut proj = Project::new(name.to_string(), ram);

    prog.call_graph
        .add_vertex(
            CallTarget::Todo(
                Rvalue::new_u64(entry),
                Some(name.to_string()),
                Uuid::new_v4(),
            )
        );

    for export in pe.exports {
        debug!("adding export: {:?}", &export);
        prog.call_graph
            .add_vertex(
                CallTarget::Todo(
                    Rvalue::new_u64(export.rva as u64 + image_base),
                    Some(export.name.to_string()),
                    Uuid::new_v4(),
                )
            );
    }

    for import in pe.imports {
        debug!(
            "adding import: {:?} @ {:#x}",
            &import,
            import.rva + pe.image_base
        );
        prog.call_graph.add_vertex(CallTarget::Symbolic(import.name.into_owned(), Uuid::new_v4()));
    }

    proj.comments.insert(("base".to_string(), entry), "main".to_string());
    proj.code.push(prog);
    Ok((proj, Machine::Ia32))
}