Repository: denoland/deno
File: cli/standalone/serialization.rs (Rust)

Code before:
    let npm_snapshot =
      npm_snapshot.map(serialize_npm_snapshot).unwrap_or_default();
    write_bytes_with_len(&mut bytes, &npm_snapshot);
  }
  // 3. Remote modules
  {
    let update_index = bytes.len();
    bytes.extend_from_slice(&(0_u64).to_le_bytes());
    let start_index = bytes.len();
    remote_modules.write(&mut bytes)?;
    let length = bytes.len() - start_index;
    let length_bytes = (length as u64).to_le_bytes();
    bytes[update_index..update_index + length_bytes.len()]
      .copy_from_slice(&length_bytes);
  }
  // 4. VFS
  {
    let serialized_vfs = serde_json::to_string(&vfs.root)?;
    write_bytes_with_len(&mut bytes, serialized_vfs.as_bytes());
    let vfs_bytes_len = vfs.files.iter().map(|f| f.len() as u64).sum::<u64>();
    bytes.extend_from_slice(&vfs_bytes_len.to_le_bytes());
    for file in &vfs.files {
      bytes.extend_from_slice(file);
    }
  }

  // write the magic bytes at the end so we can use it
  // to make sure we've deserialized correctly
  bytes.extend_from_slice(MAGIC_BYTES);

  Ok(bytes)
}

pub struct DeserializedDataSection {
  pub metadata: Metadata,
  pub npm_snapshot: Option<ValidSerializedNpmResolutionSnapshot>,
  pub remote_modules: RemoteModulesStore,
  pub vfs_dir: VirtualDirectory,
  pub vfs_files_data: &'static [u8],
}

pub fn deserialize_binary_data_section(
  data: &'static [u8],
) -> Result<Option<DeserializedDataSection>, AnyError> {
  fn read_bytes_with_len(input: &[u8]) -> Result<(&[u8], &[u8]), AnyError> {
    let (input, len) = read_u64(input)?;
    let (input, data) = read_bytes(input, len as usize)?;
    Ok((input, data))
  }

  fn read_magic_bytes(input: &[u8]) -> Result<(&[u8], bool), AnyError> {

Review comment (suggestion):
We also now surface if the capacity couldn't be allocated as an error instead of panicking.

Code after:
    {
      builder.append_le(npm_snapshot.len() as u64);
      builder.append(&npm_snapshot);
    }
    // 3. Remote modules
    {
      builder.append_le(remote_modules_len.get()); // this will be properly initialized on the second pass
      let start_index = builder.len();
      remote_modules.write(builder);
      remote_modules_len.set((builder.len() - start_index) as u64);
    }
    // 4. VFS
    {
      builder.append_le(serialized_vfs.len() as u64);
      builder.append(&serialized_vfs);
      let vfs_bytes_len = vfs.files.iter().map(|f| f.len() as u64).sum::<u64>();
      builder.append_le(vfs_bytes_len);
      for file in &vfs.files {
        builder.append(file);
      }
    }

    // write the magic bytes at the end so we can use it
    // to make sure we've deserialized correctly
    builder.append(MAGIC_BYTES);
  })?;

  Ok(bytes)
}

pub struct DeserializedDataSection {
  pub metadata: Metadata,
  pub npm_snapshot: Option<ValidSerializedNpmResolutionSnapshot>,
  pub remote_modules: RemoteModulesStore,
  pub vfs_dir: VirtualDirectory,
  pub vfs_files_data: &'static [u8],
}

pub fn deserialize_binary_data_section(
  data: &'static [u8],
) -> Result<Option<DeserializedDataSection>, AnyError> {
  fn read_bytes_with_len(input: &[u8]) -> Result<(&[u8], &[u8]), AnyError> {
    let (input, len) = read_u64(input)?;
    let (input, data) = read_bytes(input, len as usize)?;
    Ok((input, data))
  }

  fn read_magic_bytes(input: &[u8]) -> Result<(&[u8], bool), AnyError> {
    if input.len() < MAGIC_BYTES.len() {
      bail!("Unexpected end of data. Could not find magic bytes.");
    }