Skip to content

Commit

Permalink
Merge pull request #144 from etaoins/make-file-id-nonzero
Browse files Browse the repository at this point in the history
Make `FileId` non-zero
  • Loading branch information
brendanzab authored Jan 5, 2020
2 parents 461beac + 11f3c18 commit c760bff
Showing 1 changed file with 29 additions and 5 deletions.
34 changes: 29 additions & 5 deletions codespan/src/file.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#[cfg(feature = "serialization")]
use serde::{Deserialize, Serialize};
use std::num::NonZeroU32;
use std::{error, fmt};

use crate::{ByteIndex, ColumnIndex, LineIndex, LineOffset, Location, RawIndex, Span};
Expand Down Expand Up @@ -66,8 +67,31 @@ impl fmt::Display for SpanOutOfBoundsError {
/// A handle that points to a file in the database.
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
pub struct FileId(u32);
pub struct FileId(NonZeroU32);

// `HeapSizeOf` isn't implemented for `NonZeroU32` and we can't add it due to trait orphan rules
#[cfg(feature = "memory_usage")]
impl heapsize::HeapSizeOf for FileId {
fn heap_size_of_children(&self) -> usize {
0
}
}

impl FileId {
/// Offset of our `FileId`'s numeric value to an index on `Files::files`.
///
/// This is to ensure the first `FileId` is non-zero for memory layout optimisations (e.g.
/// `Option<FileId>` is 4 bytes)
const OFFSET: u32 = 1;

fn new(index: usize) -> FileId {
FileId(NonZeroU32::new(index as u32 + Self::OFFSET).unwrap())
}

fn get(self) -> usize {
(self.0.get() - Self::OFFSET) as usize
}
}

/// A database of source files.
#[derive(Clone, Debug, Default)]
Expand All @@ -84,7 +108,7 @@ impl Files {
/// Add a file to the database, returning the handle that can be used to
/// refer to it again.
pub fn add(&mut self, name: impl Into<String>, source: impl Into<String>) -> FileId {
let file_id = FileId(self.files.len() as u32);
let file_id = FileId::new(self.files.len());
self.files.push(File::new(name.into(), source.into()));
file_id
}
Expand All @@ -100,13 +124,13 @@ impl Files {
/// Get a the source file using the file id.
// FIXME: return an option or result?
fn get(&self, file_id: FileId) -> &File {
&self.files[file_id.0 as usize]
&self.files[file_id.get()]
}

/// Get a the source file using the file id.
// FIXME: return an option or result?
fn get_mut(&mut self, file_id: FileId) -> &mut File {
&mut self.files[file_id.0 as usize]
&mut self.files[file_id.get()]
}

/// Get the name of the source file.
Expand Down

0 comments on commit c760bff

Please sign in to comment.