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:
| Service | Feature | Method |
|---|---|---|
| AccurateRip | accuraterip | Toc::accuraterip_id |
| CDDB | cddb | Toc::cddb_id |
| CUETools Database | ctdb | Toc::ctdb_id |
| MusicBrainz | musicbrainz | Toc::musicbrainz_id |
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
impl Toc
Sourcepub fn accuraterip_id(&self) -> AccurateRip
Available on crate feature accuraterip only.
pub fn accuraterip_id(&self) -> AccurateRip
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],
);Sourcepub fn accuraterip_checksum_url(&self) -> String
Available on crate feature accuraterip only.
pub fn accuraterip_checksum_url(&self) -> String
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",
);Sourcepub fn accuraterip_parse_checksums(
&self,
bin: &[u8],
) -> Result<Vec<BTreeMap<u32, u8>>, TocError>
Available on crate feature accuraterip only.
pub fn accuraterip_parse_checksums( &self, bin: &[u8], ) -> Result<Vec<BTreeMap<u32, u8>>, TocError>
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
impl Toc
Sourcepub fn cddb_id(&self) -> Cddb
Available on crate feature cddb only.
pub fn cddb_id(&self) -> Cddb
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
impl Toc
Sourcepub fn ctdb_id(&self) -> ShaB64
Available on crate feature ctdb only.
pub fn ctdb_id(&self) -> ShaB64
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-",
);Sourcepub fn ctdb_url(&self) -> String
Available on crate feature ctdb only.
pub fn ctdb_url(&self) -> String
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-",
);Sourcepub fn ctdb_checksum_url(&self) -> String
Available on crate feature ctdb only.
pub fn ctdb_checksum_url(&self) -> String
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",
);Sourcepub fn ctdb_parse_checksums(
&self,
xml: &str,
) -> Result<Vec<BTreeMap<u32, u16>>, TocError>
Available on crate feature ctdb only.
pub fn ctdb_parse_checksums( &self, xml: &str, ) -> Result<Vec<BTreeMap<u32, u16>>, TocError>
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
impl Toc
Sourcepub fn musicbrainz_id(&self) -> ShaB64
Available on crate feature musicbrainz only.
pub fn musicbrainz_id(&self) -> ShaB64
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-",
);Sourcepub fn musicbrainz_url(&self) -> String
Available on crate feature musicbrainz only.
pub fn musicbrainz_url(&self) -> String
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
impl Toc
Sourcepub fn from_cdtoc<S>(src: S) -> Result<Self, TocError>
pub fn from_cdtoc<S>(src: S) -> Result<Self, TocError>
§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.
Sourcepub fn from_durations<I>(src: I, leadin: Option<u32>) -> Result<Self, TocError>where
I: IntoIterator<Item = Duration>,
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.
Sourcepub fn from_parts(
audio: Vec<u32>,
data: Option<u32>,
leadout: u32,
) -> Result<Self, TocError>
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.
Sourcepub fn set_audio_leadin(&mut self, leadin: u32) -> Result<(), TocError>
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.
Sourcepub fn set_kind(&mut self, kind: TocKind) -> Result<(), TocError>
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
impl Toc
Sourcepub const fn audio_leadin(&self) -> u32
pub const fn audio_leadin(&self) -> u32
Sourcepub const fn audio_leadin_normalized(&self) -> u32
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);Sourcepub const fn audio_leadout(&self) -> u32
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);Sourcepub const fn audio_leadout_normalized(&self) -> u32
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);Sourcepub const fn audio_sectors(&self) -> &[u32]
pub const fn audio_sectors(&self) -> &[u32]
Sourcepub fn audio_track(&self, num: usize) -> Option<Track>
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.
Sourcepub const fn audio_tracks(&self) -> Tracks<'_> ⓘ
pub const fn audio_tracks(&self) -> Tracks<'_> ⓘ
Sourcepub const fn data_sector(&self) -> Option<u32>
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));Sourcepub const fn data_sector_normalized(&self) -> Option<u32>
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));Sourcepub const fn has_data(&self) -> bool
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);Sourcepub const fn htoa(&self) -> Option<Track>
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);Sourcepub const fn kind(&self) -> TocKind
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);Sourcepub const fn leadin_normalized(&self) -> u32
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);Sourcepub const fn leadout_normalized(&self) -> u32
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);Trait Implementations§
Source§impl<'de> Deserialize<'de> for Toc
Available on crate feature serde only.
impl<'de> Deserialize<'de> for Toc
serde only.