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: lockfile.rs
    path of file: ./repos/cargo/src/cargo/ops
    
    the code of the file until where you have to start completion: use std::io::prelude::*;

use crate::core::{resolver, Resolve, ResolveVersion, Workspace};
use crate::util::errors::CargoResult;
use crate::util::Filesystem;

use anyhow::Context as _;

#[tracing::instrument(skip_all)]
pub fn load_pkg_lockfile(ws: &Workspace<'_>) -> CargoResult<Option<Resolve>> {
    let lock_root = lock_root(ws);
    if !lock_root.as_path_unlocked().join("Cargo.lock").exists() {
        return Ok(None);
    }

    let mut f = lock_root.open_ro_shared("Cargo.lock", ws.gctx(), "Cargo.lock file")?;

    let mut s = String::new();
    f.read_to_string(&mut s)
        .with_context(|| format!("failed to read file: {}", f.path().display()))?;

    let resolve = (|| -> CargoResult<Option<Resolve>> {
        let v: resolver::EncodableResolve = toml::from_
    
fn serialize_resolve(resolve: &Resolve, orig: Option<&str>) -> String {
    let toml = toml::Table::try_from(resolve).unwrap();

    let mut out = String::new();

    // At the start of the file we notify the reader that the file is generated.
    // Specifically Phabricator ignores files containing "@generated", so we use that.
    let marker_line = "# This file is automatically @generated by Cargo.";
    let extra_line = "# It is not intended for manual editing.";
    out.push_str(marker_line);
    out.push('\n');
    out.push_str(extra_line);
    out.push('\n');
    // and preserve any other top comments
    if let Some(orig) = orig {
        let mut comments = orig.lines().take_while(|line| line.starts_with('#'));
        if let Some(first) = comments.next() {
            if first != marker_line {
                out.push_str(first);
                out.push('\n');
            }
            if let Some(second) = comments.next() {
                if second != extra_line {
                    out.push_str(second);
                    out.push('\n');
                }
                for line in comments {
                    out.push_str(line);
                    out.push('\n');
                }
            }
        }
    }

    if let Some(version) = toml.get("version") {
        out.push_str(&format!("version = {}\n\n", version));
    }

    let deps = toml["package"].as_array().unwrap();
    for dep in deps {
        let dep = dep.as_table().unwrap();

        out.push_str("[[package]]\n");
        emit_package(dep, &mut out);
    }

    if let Some(patch) = toml.get("patch") {
        let list = patch["unused"].as_array().unwrap();
        for entry in list {
            out.push_str("[[patch.unused]]\n");
            emit_package(entry.as_table().unwrap(), &mut out);
            out.push('\n');
        }
    }

    if let Some(meta) = toml.get("metadata") {
        // 1. We need to ensure we print the entire tree, not just the direct members of `metadata`
        //    (which `toml_edit::Table::to_string` only shows)
        // 2. We need to ensure all children tables have `metadata.` prefix
        let meta_table = meta
            .as_table()
            .expect("validation ensures this is a table")
            .clone();
        let mut meta_doc = toml::Table::new();
        meta_doc.insert("metadata".to_owned(), toml::Value::Table(meta_table));

        out.push_str(&meta_doc.to_string());
    }

    // Historical versions of Cargo in the old format accidentally left trailing
    // blank newlines at the end of files, so we just leave that as-is. For all
    // encodings going forward, though, we want to be sure that our encoded lock
    // file doesn't contain any trailing newlines so trim out the extra if
    // necessary.
    if resolve.version() >= ResolveVersion::V2 {
        while out.ends_with("\n\n") {
            out.pop();
        }
    }
    out
}