[vlc-devel] [RFC: PATCH 2/2] stream filter: Add rust based cuesheet module
Alexandre Janniaux
ajanni at videolabs.io
Fri Sep 11 17:12:17 CEST 2020
Hi
On Fri, Sep 11, 2020 at 06:54:45PM +0530, Kartik Ohri wrote:
> > > + let mut cuesheet = Cuesheet::default();
> > > + let reader = BufReader::new(stream);
> > > + reader.lines().for_each(|line| {
> > > + line.map(|l| cuesheet.process_line(l.as_str()));
> > > + });
> >
> > In its current form, the playlist demux will open regardless
> > of whether the line processing failed or not and the error is
> > dropped.
> >
> > It means that if a line fails to proceed, it might just be
> > dropped silently, instead of failing to open the module. I'm
> > not sure this is what we want here, though I haven't checked
> > the other playlist modules.
> >
> >
> It was intentional. I have checked a few other modules and there is error
> handling for different parts. However, in this the failure will occur only
> if Rust is unable to convert the string into Utf8, this case is not
> relevant to the C modules. How do you suggest to approach this ? My
> intention was to continue processing and later decide while creating input
> items if anything necessary is missing then handle the error there.
If it doesn't need UTF-8, maybe it can use a different String
type so as to avoid the error case? In any case, if the file
is not valid it should probably not silently drop some lines
> > > +#[no_mangle]
> > > +pub unsafe extern fn cuesheet_get_tracks_number(c_cuesheet : *mut
> > CCuesheet)
> > > + -> c_int {
> > > + (*c_cuesheet).cuesheet.tracks.len() as i32
> >
> > It's weird that you cast into i32 to return a c_int, neaning
> > that it will probably error out if both are not the same.
> >
> >
> I was under the impression that the two were equivalent. IIRC, currently
> all rust supported platforms have 32 bit integers in C.
In cases in which they are equivalent, it's still clearer with
a cast to `c_int` when you want to return a `c_int`. ;)
> > > +impl Cuesheet {
> > > + pub fn process_line(&mut self, line: &str) -> Option<()> {
> >
> > It seems to me that this could actually be an implementation of
> > the trait FromStr, and thus usage could be done though the more
> > idiomatic str/String::parse().
> >
> >
> I didn't use the FromStr trait because a single line does not describe the
> struct completely. However, I can try to read all lines into a single
> string first and then use FromStr on it.
>
Actually you're right, no need for FromStr here then.
> > > + let parts = parse_line(line);
> > > + let keyword = parts[0].as_str();
> > > + if !self.is_processing_tracks {
> > > + match keyword {
> > > + "FILE" => {
> > > + self.file_name = parts[1].to_owned();
> > > + self.file_type = parts[2].to_owned();
> > > + }
> > > + "TITLE" => self.title = parts[1].to_owned(),
> > > + "PERFORMER" => self.performer = parts[1].to_owned(),
> > > + "REM" => {
> > > + self.comments
> > > + .insert(parts[1].to_owned().to_lowercase(),
> > parts[2].to_owned());
> > > + }
> > > + "TRACK" => self.is_processing_tracks = true,
> > > + _ => {}
> > > + };
> > > + }
> > > + if self.is_processing_tracks {
> > > + if keyword == "TRACK" {
> > > + let mut track = CuesheetTrack::default();
> > > + track.item_position =
> > parts[1].to_owned().parse::<u8>().ok()?;
> > > + track.item_type = parts[2].to_owned();
> > > + self.tracks.push(track);
> > > + } else {
> > > + self.tracks.last_mut()?.process_track(line);
> > > + }
> > > + }
> > > + Some(())
> > > + }
> > > +}
> > > +
> > > +impl CuesheetTrack {
> > > + fn process_track(&mut self, line: &str) -> Option<()> {
> >
> > Same as above.
> >
>
> I can try to use FromStr here as well but it is duplicating work. In
> CueSheet, we''ll obtain every line one by one and then create a new string.
> Then, again in CuesheetTrack, iterate the String to break into lines.
Indeed too, forget about my remark. :)
> > > + let parts = parse_line(line);
> > > + let keyword = parts[0].as_str();
> > > + match keyword {
> > > + "TITLE" => self.item_title = parts[1].to_owned(),
> > > + "PERFORMER" => self.item_performer = parts[1].to_owned(),
> > > + "INDEX" => {
> > > + let index_position =
> > parts[1].to_owned().parse::<u8>().ok()?;
> > > + if index_position == 1 {
> > > + self.item_begin_duration = parts[2].to_owned();
> > > + }
> > > + }
> > > + _ => {}
> > > + };
> > > + Some(())
> > > + }
> > > +}
> > > --
> > > 2.25.1
> >
> > Regards,
> > --
> > Alexandre Janniaux
> > Videolabs
> > _______________________________________________
> > vlc-devel mailing list
> > To unsubscribe or modify your subscription options:
> > https://mailman.videolan.org/listinfo/vlc-devel
Regards,
--
Alexandre Janniaux
Videolabs
More information about the vlc-devel
mailing list