Toc

Struct Toc 

Source
pub struct Toc { /* private fields */ }
Expand description

§CDTOC.

This struct holds a CD’s parsed table of contents.

You can initialize it using a CDTOC-style metadata value via Toc::from_cdtoc or manually with Toc::from_parts.

Once parsed, you can obtain things like the number of audio tracks, their sector positions, information about the session(s) and so on.

Many online databases derive their unique disc IDs using tables of content too. Toc can give you the following, provided the corresponding crate feature(s) are enabled:

If you don’t care about any of those, import this crate with default-features = false to skip the overhead.

§Examples

use cdtoc::Toc;

// From a CDTOC string.
let toc1 = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();

// From the raw parts.
let toc2 = Toc::from_parts(
    vec![150, 11563, 25174, 45863],
    None,
    55370,
).unwrap();

// Either way gets you to the same place.
assert_eq!(toc1, toc2);

// You can also get a CDTOC-style string back at any time:
assert_eq!(toc1.to_string(), "4+96+2D2B+6256+B327+D84A");

Implementations§

Source§

impl Toc

Source

pub fn accuraterip_id(&self) -> AccurateRip

Available on crate feature accuraterip only.
§AccurateRip ID.

This returns the AccurateRip ID corresponding to the table of contents.

§Examples
use cdtoc::Toc;

let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();
let ar_id = toc.accuraterip_id();

// Usually you'll want this value as a string:
assert_eq!(
    ar_id.to_string(),
    "004-0002189a-00087f33-1f02e004",
);

// But you can also get a binary version matching the format of the
// checksum bin files:
assert_eq!(
    <[u8; 13]>::from(ar_id),
    [4, 154, 24, 2, 0, 51, 127, 8, 0, 4, 224, 2, 31],
);
Source

pub fn accuraterip_checksum_url(&self) -> String

Available on crate feature accuraterip only.
§AccurateRip Checksum URL.

This returns the URL where you can download the v1 and v2 checksums for the disc, provided it is actually in the AccurateRip database. (If it isn’t, their server will return a 404.)

§Examples
use cdtoc::Toc;

let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(
    toc.accuraterip_checksum_url(),
    "http://www.accuraterip.com/accuraterip/a/9/8/dBAR-004-0002189a-00087f33-1f02e004.bin",
);
Source

pub fn accuraterip_parse_checksums( &self, bin: &[u8], ) -> Result<Vec<BTreeMap<u32, u8>>, TocError>

Available on crate feature accuraterip only.
§Parse Checksums.

This will parse the v1 and v2 track checksums from a raw AccurateRip checksum bin file.

See AccurateRip::parse_checksums for more information.

§Errors

This will return an error if parsing is unsuccessful, or the result is empty.

Source§

impl Toc

Source

pub fn cddb_id(&self) -> Cddb

Available on crate feature cddb only.
§CDDB ID.

This returns the CDDB ID corresponding to the table of contents.

§Examples
use cdtoc::Toc;

let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();
let cddb_id = toc.cddb_id();

// Usually you'll want this value as a string:
assert_eq!(
    cddb_id.to_string(),
    "1f02e004",
);

// But you can also get it as a `u32`:
assert_eq!(
    u32::from(cddb_id),
    520_282_116,
);
Source§

impl Toc

Source

pub fn ctdb_id(&self) -> ShaB64

Available on crate feature ctdb only.
§CUETools Database ID.

This returns the CUETools Database ID corresponding to the table of contents.

§Examples
use cdtoc::Toc;

let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(
    toc.ctdb_id().to_string(),
    "VukMWWItblELRM.CEFpXxw0FlME-",
);
Source

pub fn ctdb_url(&self) -> String

Available on crate feature ctdb only.
§CUETools Database URL.

This URL can be visited in a web browser to view the details for the disc (if it is present in the database).

See also: Toc::ctdb_checksum_url

§Examples
use cdtoc::Toc;

let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();

// Note: the CUETools website lacks SSL/TLS support.
assert_eq!(
    toc.ctdb_url(),
    "http://db.cuetools.net/?tocid=VukMWWItblELRM.CEFpXxw0FlME-",
);
Source

pub fn ctdb_checksum_url(&self) -> String

Available on crate feature ctdb only.
§CUETools Database Checksum URL.

This URL can be used to fetch XML-formatted checksums and metadata for the disc (if it is present in the database).

See also: Toc::ctdb_url

§Examples
use cdtoc::Toc;

let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();

// Note: the CUETools website lacks SSL/TLS support.
assert_eq!(
    toc.ctdb_checksum_url(),
    "http://db.cuetools.net/lookup2.php?version=3&ctdb=1&fuzzy=1&toc=0:11413:25024:45713:55220",
);
Source

pub fn ctdb_parse_checksums( &self, xml: &str, ) -> Result<Vec<BTreeMap<u32, u16>>, TocError>

Available on crate feature ctdb only.
§Parse Checksums.

This will parse the track checksums from an XML CTDB lookup.

The return result is a vector — indexed by track number (n-1) — of checksum => confidence pairs.

§Errors

This method uses naive parsing so does not worry about strict XML validation, but will return an error if other parsing errors are encountered or no checksums are found.

Source§

impl Toc

Source

pub fn musicbrainz_id(&self) -> ShaB64

Available on crate feature musicbrainz only.
§MusicBrainz ID.

This returns the MusicBrainz ID corresponding to the table of contents.

§Examples
use cdtoc::Toc;

let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(
    toc.musicbrainz_id().to_string(),
    "nljDXdC8B_pDwbdY1vZJvdrAZI4-",
);
Source

pub fn musicbrainz_url(&self) -> String

Available on crate feature musicbrainz only.
§MusicBrainz URL.

This URL can be visited in a web browser to view the details for the disc (if it is present in the database).

§Examples
use cdtoc::Toc;

let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(
    toc.musicbrainz_url(),
    "https://musicbrainz.org/cdtoc/nljDXdC8B_pDwbdY1vZJvdrAZI4-",
);
Source§

impl Toc

Source

pub fn from_cdtoc<S>(src: S) -> Result<Self, TocError>
where S: AsRef<str>,

§From CDTOC Metadata Tag.

Instantiate a new Toc from a CDTOC metadata tag value, of the format described here.

§Examples
use cdtoc::Toc;

let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();
§Errors

This will return an error if the tag value is improperly formatted, the audio track count is outside 1..=99, there are too many or too few sectors, the leadin is less than 150, or the sectors are ordered incorrectly.

Source

pub fn from_durations<I>(src: I, leadin: Option<u32>) -> Result<Self, TocError>
where I: IntoIterator<Item = Duration>,

§From Durations.

This will attempt to create an audio-only Toc from the track durations. (Needless to say, this will only work if all tracks are present and in the right order!)

If you happen to know the disc’s true leadin offset you can specify it, otherwise the “industry default” value of 150 will be assumed.

To create a mixed-mode Toc from scratch, use Toc::from_parts instead so you can specify the location of the data session.

§Examples
use cdtoc::{Toc, Duration};

let toc = Toc::from_durations(
    [
        Duration::from(46650_u64),
        Duration::from(41702_u64),
        Duration::from(30295_u64),
        Duration::from(37700_u64),
        Duration::from(40050_u64),
        Duration::from(53985_u64),
        Duration::from(37163_u64),
        Duration::from(59902_u64),
    ],
    None,
).unwrap();
assert_eq!(
    toc.to_string(),
    "8+96+B6D0+159B6+1D00D+26351+2FFC3+3D2A4+463CF+54DCD",
);
§Errors

This will return an error if the track count is outside 1..=99, the leadin is less than 150, or the sectors overflow u32.

Source

pub fn from_parts( audio: Vec<u32>, data: Option<u32>, leadout: u32, ) -> Result<Self, TocError>

§From Parts.

Instantiate a new Toc by manually specifying the (starting) sectors for each audio track, data track (if any), and the leadout.

If a data track is supplied, it must fall between the last audio track and leadout, or come before either.

§Examples
use cdtoc::Toc;

let toc = Toc::from_parts(
    vec![150, 11563, 25174, 45863],
    None,
    55370,
).unwrap();

assert_eq!(toc.to_string(), "4+96+2D2B+6256+B327+D84A");

// Sanity matters; the leadin, for example, can't be less than 150.
assert!(Toc::from_parts(
    vec![0, 10525],
    None,
    15000,
).is_err());
§Errors

This will return an error if the audio track count is outside 1..=99, the leadin is less than 150, or the sectors are in the wrong order.

Source

pub fn set_audio_leadin(&mut self, leadin: u32) -> Result<(), TocError>

§Set Audio Leadin.

Set the audio leadin, nudging all entries up or down accordingly ( including data and leadout).

Note: this method cannot be used for data-first mixed-mode CDs.

§Examples
use cdtoc::{Toc, TocKind};

let mut toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(toc.audio_leadin(), 150);

// Bump it up to 182.
assert!(toc.set_audio_leadin(182).is_ok());
assert_eq!(toc.audio_leadin(), 182);
assert_eq!(
    toc.to_string(),
    "4+B6+2D4B+6276+B347+D86A",
);

// Back down to 150.
assert!(toc.set_audio_leadin(150).is_ok());
assert_eq!(toc.audio_leadin(), 150);
assert_eq!(
    toc.to_string(),
    "4+96+2D2B+6256+B327+D84A",
);

// For CD-Extra, the data track will get nudged too.
toc = Toc::from_cdtoc("3+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(toc.kind(), TocKind::CDExtra);
assert_eq!(toc.audio_leadin(), 150);
assert_eq!(toc.data_sector(), Some(45863));

assert!(toc.set_audio_leadin(182).is_ok());
assert_eq!(toc.audio_leadin(), 182);
assert_eq!(toc.data_sector(), Some(45895));

// And back again.
assert!(toc.set_audio_leadin(150).is_ok());
assert_eq!(toc.audio_leadin(), 150);
assert_eq!(toc.data_sector(), Some(45863));
§Errors

This will return an error if the leadin is less than 150, the CD format is data-first, or the nudging causes the sectors to overflow u32.

Source

pub fn set_kind(&mut self, kind: TocKind) -> Result<(), TocError>

§Set Media Kind.

This method can be used to override the table of content’s derived media format.

This is weird, but might come in handy if you need to correct a not- quite-right CDTOC metadata tag value, such as one that accidentally included the data session in its leading track count or ordered the sectors of a data-audio CD sequentially.

§Examples
use cdtoc::{Toc, TocKind};

// This will be interpreted as audio-only.
let mut toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();

// If the track count was wrong and it is really a mixed-mode CD-Extra
// disc, this will fix it right up:
assert!(toc.set_kind(TocKind::CDExtra).is_ok());
assert_eq!(
    toc.to_string(),
    "3+96+2D2B+6256+B327+D84A",
);
§Errors

This will return an error if there aren’t enough sectors or tracks for the new kind.

Source§

impl Toc

Source

pub const fn audio_leadin(&self) -> u32

§Audio Leadin.

Return the leadin of the audio session, sometimes called the “offset”. In practice, this is just where the first audio track begins.

§Examples
use cdtoc::Toc;

let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(toc.audio_leadin(), 150);
Source

pub const fn audio_leadin_normalized(&self) -> u32

§Normalized Audio Leadin.

This is the same as Toc::audio_leadin, but without the mandatory 150-sector CD lead-in.

§Examples
use cdtoc::Toc;

let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(toc.audio_leadin(), 150);
assert_eq!(toc.audio_leadin_normalized(), 0);
Source

pub const fn audio_leadout(&self) -> u32

§Audio Leadout.

Return the leadout for the audio session. This is usually the same as Toc::leadout, but for CD-Extra discs, the audio leadout is actually the start of the data, minus a gap of 11_400.

§Examples
use cdtoc::Toc;

let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(toc.audio_leadout(), 55370);
Source

pub const fn audio_leadout_normalized(&self) -> u32

§Normalized Audio Leadout.

This is the same as Toc::audio_leadout, but without the mandatory 150-sector CD lead-in.

§Examples
use cdtoc::Toc;

let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(toc.audio_leadout(), 55370);
assert_eq!(toc.audio_leadout_normalized(), 55220);
Source

pub const fn audio_len(&self) -> usize

§Number of Audio Tracks.
§Examples
use cdtoc::Toc;

let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(toc.audio_len(), 4);
Source

pub const fn audio_sectors(&self) -> &[u32]

§Audio Sectors.

Return the starting positions of each audio track.

§Examples
use cdtoc::Toc;

let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(toc.audio_sectors(), &[150, 11563, 25174, 45863]);
Source

pub fn audio_track(&self, num: usize) -> Option<Track>

§Audio Track.

Return the details of a given audio track on the disc, or None if the track number is out of range.

Source

pub const fn audio_tracks(&self) -> Tracks<'_>

§Audio Tracks.

Return an iterator of Track details covering the whole album.

Source

pub const fn data_sector(&self) -> Option<u32>

§Data Sector.

Return the starting position of the data track, if any.

§Examples
use cdtoc::Toc;

// No data here.
let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(toc.data_sector(), None);

// This CD-Extra has data, though!
let toc = Toc::from_cdtoc("3+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(toc.data_sector(), Some(45_863));
Source

pub const fn data_sector_normalized(&self) -> Option<u32>

§Normalized Data Sector.

This is the same as Toc::data_sector, but without the mandatory 150-sector CD lead-in.

§Examples
use cdtoc::Toc;

// No data here.
let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(toc.data_sector(), None);

// This CD-Extra has data, though!
let toc = Toc::from_cdtoc("3+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(toc.data_sector(), Some(45_863));
assert_eq!(toc.data_sector_normalized(), Some(45_713));
Source

pub const fn has_data(&self) -> bool

§Has Data?

This returns true for mixed-mode CDs and false for audio-only ones.

§Examples
use cdtoc::Toc;

let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(toc.has_data(), false);

let toc = Toc::from_cdtoc("3+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(toc.has_data(), true);
Source

pub const fn htoa(&self) -> Option<Track>

§HTOA Pre-gap “Track”.

Return a Track object representing the space between the mandatory disc leadin (150) and the start of the first audio track, if any.

Such regions usually only contain a small amount of silence — extra padding, basically — but every once in a while might be a secret bonus song.

§Examples
use cdtoc::Toc;

// This disc has no HTOA.
let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();
assert!(toc.htoa().is_none());

// But this one does!
let toc = Toc::from_cdtoc("15+247E+2BEC+4AF4+7368+9704+B794+E271+110D0+12B7A+145C1+16CAF+195CF+1B40F+1F04A+21380+2362D+2589D+2793D+2A760+2DA32+300E1+32B46").unwrap();
let htoa = toc.htoa().unwrap();
assert!(htoa.is_htoa()); // Should always be true.

// HTOAs have no track number.
assert_eq!(htoa.number(), 0);

// Their position is also technically invalid.
assert!(! htoa.position().is_valid());

// Their ranges are normal, though.
assert_eq!(htoa.sector_range(), 150..9342);
Source

pub const fn kind(&self) -> TocKind

§CD Format.

This returns the TocKind corresponding to the table of contents, useful if you want to know whether or not the disc has a data session, and where it is in relation to the audio session.

§Examples
use cdtoc::{Toc, TocKind};

let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(toc.kind(), TocKind::Audio);

let toc = Toc::from_cdtoc("3+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(toc.kind(), TocKind::CDExtra);

let toc = Toc::from_cdtoc("3+2D2B+6256+B327+D84A+X96").unwrap();
assert_eq!(toc.kind(), TocKind::DataFirst);
Source

pub const fn leadin(&self) -> u32

§Absolute Leadin.

Return the offset of the first track (no matter the session type).

§Examples
use cdtoc::Toc;

let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(toc.leadin(), 150);
Source

pub const fn leadin_normalized(&self) -> u32

§Normalized Absolute Leadin.

This is the same as Toc::leadin, but without the mandatory 150-sector CD lead-in.

§Examples
use cdtoc::Toc;

let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(toc.leadin(), 150);
assert_eq!(toc.leadin_normalized(), 0);
Source

pub const fn leadout(&self) -> u32

§Absolute Leadout.

Return the disc leadout, regardless of whether it marks the end of the audio or data session.

§Examples
use cdtoc::Toc;

let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(toc.leadout(), 55_370);
Source

pub const fn leadout_normalized(&self) -> u32

§Normalized Absolute Leadout.

This is the same as Toc::leadout, but without the mandatory 150-sector CD lead-in.

§Examples
use cdtoc::Toc;

let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(toc.leadout(), 55_370);
assert_eq!(toc.leadout_normalized(), 55_220);
Source

pub const fn duration(&self) -> Duration

§Duration.

Return the total duration of all audio tracks.

§Examples
use cdtoc::{Duration, Toc};

let toc = Toc::from_cdtoc("4+96+2D2B+6256+B327+D84A").unwrap();
assert_eq!(
    toc.duration(),
    toc.audio_tracks().map(|t| t.duration()).sum(),
);

Trait Implementations§

Source§

impl Clone for Toc

Source§

fn clone(&self) -> Toc

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Toc

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for Toc

Available on crate feature serde only.
Source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Display for Toc

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl From<&Toc> for AccurateRip

Source§

fn from(src: &Toc) -> Self

Converts to this type from the input type.
Source§

impl From<&Toc> for Cddb

Source§

fn from(src: &Toc) -> Self

Converts to this type from the input type.
Source§

impl Hash for Toc

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for Toc

Source§

fn eq(&self, other: &Toc) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for Toc

Available on crate feature serde only.
Source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Eq for Toc

Source§

impl StructuralPartialEq for Toc

Auto Trait Implementations§

§

impl Freeze for Toc

§

impl RefUnwindSafe for Toc

§

impl Send for Toc

§

impl Sync for Toc

§

impl Unpin for Toc

§

impl UnwindSafe for Toc

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,