diff --git a/musikr/src/main/jni/src/jbuilder.rs b/musikr/src/main/jni/src/jbuilder.rs index 1cd16db5b..990902954 100644 --- a/musikr/src/main/jni/src/jbuilder.rs +++ b/musikr/src/main/jni/src/jbuilder.rs @@ -1,10 +1,12 @@ -use jni::{objects::{JByteArray, JClass, JMap, JObject, JString, JValueGen}, sys::jlong, JNIEnv}; -use std::rc::Rc; -use std::cell::RefCell; - -use crate::taglib::{ - id3v1, id3v2, xiph, mp4, tk, audioproperties, +use jni::{ + objects::{JObject, JValueGen}, + sys::jlong, + JNIEnv, }; +use std::cell::RefCell; +use std::rc::Rc; + +use crate::taglib::{audioproperties, id3v1, id3v2, mp4, xiph}; use crate::tagmap::JTagMap; @@ -41,7 +43,7 @@ impl<'local, 'file_ref> JMetadataBuilder<'local, 'file_ref> { self.id3v2.add_id("TALB", tag.album().to_string()); self.id3v2.add_id("TRCK", tag.track().to_string()); self.id3v2.add_id("TYER", tag.year().to_string()); - + let genre = tag.genre_index(); if genre != 255 { self.id3v2.add_id("TCON", genre.to_string()); @@ -56,7 +58,8 @@ impl<'local, 'file_ref> JMetadataBuilder<'local, 'file_ref> { for mut frame in frames.to_vec() { if let Some(text_frame) = frame.as_text_identification() { if let Some(field_list) = text_frame.field_list() { - let values: Vec = field_list.to_vec() + let values: Vec = field_list + .to_vec() .into_iter() .map(|s| s.to_string()) .collect(); @@ -103,16 +106,19 @@ impl<'local, 'file_ref> JMetadataBuilder<'local, 'file_ref> { pub fn set_mp4(&mut self, tag: &mp4::MP4Tag) { let map = tag.item_map().to_hashmap(); - + for (key, item) in map { if key == "covr" { if let Some(mp4::MP4Data::CoverArtList(cover_list)) = item.data() { let covers = cover_list.to_vec(); // Prefer PNG/JPEG covers let preferred_cover = covers.iter().find(|c| { - matches!(c.format(), mp4::CoverArtFormat::PNG | mp4::CoverArtFormat::JPEG) + matches!( + c.format(), + mp4::CoverArtFormat::PNG | mp4::CoverArtFormat::JPEG + ) }); - + if let Some(cover) = preferred_cover { self.cover = Some(cover.data().to_vec()); } else if let Some(first_cover) = covers.first() { @@ -125,7 +131,8 @@ impl<'local, 'file_ref> JMetadataBuilder<'local, 'file_ref> { if let Some(data) = item.data() { match data { mp4::MP4Data::StringList(list) => { - let values: Vec = list.to_vec().into_iter().map(|s| s.to_string()).collect(); + let values: Vec = + list.to_vec().into_iter().map(|s| s.to_string()).collect(); if key.starts_with("----") { if let Some(split_idx) = key.find(':') { let (atom_name, atom_desc) = key.split_at(split_idx); @@ -158,41 +165,67 @@ impl<'local, 'file_ref> JMetadataBuilder<'local, 'file_ref> { pub fn build(&self) -> JObject { // Create Properties object - let properties_class = self.env.borrow_mut().find_class("org/oxycblt/musikr/metadata/Properties").unwrap(); + let properties_class = self + .env + .borrow_mut() + .find_class("org/oxycblt/musikr/metadata/Properties") + .unwrap(); let properties = if let Some(props) = &self.properties { let mime_type = self.mime_type.as_deref().unwrap_or("").to_string(); let j_mime_type = self.env.borrow().new_string(mime_type).unwrap(); - - self.env.borrow_mut().new_object( - properties_class, - "(Ljava/lang/String;JII)V", - &[ - JValueGen::from(&j_mime_type), - (props.length_in_milliseconds() as jlong).into(), - (props.bitrate() as i32).into(), - (props.sample_rate() as i32).into(), - ], - ).unwrap() + + self.env + .borrow_mut() + .new_object( + properties_class, + "(Ljava/lang/String;JII)V", + &[ + JValueGen::from(&j_mime_type), + (props.length_in_milliseconds() as jlong).into(), + (props.bitrate() as i32).into(), + (props.sample_rate() as i32).into(), + ], + ) + .unwrap() } else { let empty_mime = self.env.borrow().new_string("").unwrap(); - self.env.borrow_mut().new_object( - properties_class, - "(Ljava/lang/String;JII)V", - &[JValueGen::from(&empty_mime), 0i64.into(), 0i32.into(), 0i32.into()], - ).unwrap() + self.env + .borrow_mut() + .new_object( + properties_class, + "(Ljava/lang/String;JII)V", + &[ + JValueGen::from(&empty_mime), + 0i64.into(), + 0i32.into(), + 0i32.into(), + ], + ) + .unwrap() }; // Create cover byte array if present let cover_array = if let Some(cover_data) = &self.cover { - let array = self.env.borrow().new_byte_array(cover_data.len() as i32).unwrap(); - self.env.borrow().set_byte_array_region(&array, 0, bytemuck::cast_slice(cover_data)).unwrap(); + let array = self + .env + .borrow() + .new_byte_array(cover_data.len() as i32) + .unwrap(); + self.env + .borrow() + .set_byte_array_region(&array, 0, bytemuck::cast_slice(cover_data)) + .unwrap(); array.into() } else { JObject::null() }; // Create Metadata object - let metadata_class = self.env.borrow_mut().find_class("org/oxycblt/musikr/metadata/Metadata").unwrap(); + let metadata_class = self + .env + .borrow_mut() + .find_class("org/oxycblt/musikr/metadata/Metadata") + .unwrap(); self.env.borrow_mut().new_object( metadata_class, "(Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;[BLorg/oxycblt/musikr/metadata/Properties;)V", diff --git a/musikr/src/main/jni/src/jstream.rs b/musikr/src/main/jni/src/jstream.rs index c9aec1bb9..54d9261ff 100644 --- a/musikr/src/main/jni/src/jstream.rs +++ b/musikr/src/main/jni/src/jstream.rs @@ -1,7 +1,7 @@ use crate::taglib::iostream::IOStream; use crate::SharedEnv; use jni::objects::{JObject, JValue}; -use std::io::{Read, Seek, SeekFrom, Write}; +use std::io::SeekFrom; pub struct JInputStream<'local> { env: SharedEnv<'local>, diff --git a/musikr/src/main/jni/src/lib.rs b/musikr/src/main/jni/src/lib.rs index 897f93607..02bac4eee 100644 --- a/musikr/src/main/jni/src/lib.rs +++ b/musikr/src/main/jni/src/lib.rs @@ -1,36 +1,79 @@ use jni::objects::{JClass, JObject}; -use jni::sys::jstring; +use jni::sys::jobject; use jni::JNIEnv; use std::cell::RefCell; use std::rc::Rc; +mod jbuilder; mod jstream; mod taglib; mod tagmap; -mod jbuilder; +use jbuilder::JMetadataBuilder; use jstream::JInputStream; use taglib::file_ref::FileRef; -use jbuilder::JMetadataBuilder; type SharedEnv<'local> = Rc>>; #[no_mangle] pub extern "C" fn Java_org_oxycblt_musikr_metadata_MetadataJNI_openFile<'local>( - mut env: JNIEnv<'local>, + env: JNIEnv<'local>, _class: JClass<'local>, input: JObject<'local>, -) -> jstring { +) -> jobject { // Create JInputStream from the Java input stream let shared_env = Rc::new(RefCell::new(env)); - let mut stream = JInputStream::new(shared_env.clone(), input); + let stream = JInputStream::new(shared_env.clone(), input); let file_ref = FileRef::new(stream); - + let file = file_ref.file(); + let mut jbuilder = JMetadataBuilder::new(shared_env.clone()); + match file { + Some(mut file) => { + if let Some(properties) = file.audio_properties() { + jbuilder.set_properties(properties); + } + if let Some(vorbis) = file.as_vorbis() { + jbuilder.set_mime_type("audio/ogg"); + if let Some(tag) = vorbis.xiph_comments() { + jbuilder.set_xiph(&tag); + } + } + if let Some(opus) = file.as_opus() { + jbuilder.set_mime_type("audio/opus"); + if let Some(tag) = opus.xiph_comments() { + jbuilder.set_xiph(&tag); + } + } + if let Some(mut flac) = file.as_flac() { + jbuilder.set_mime_type("audio/flac"); + if let Some(tag) = flac.xiph_comments() { + jbuilder.set_xiph(&tag); + } + } + if let Some(mut mpeg) = file.as_mpeg() { + jbuilder.set_mime_type("audio/mpeg"); + if let Some(tag) = mpeg.id3v1_tag() { + jbuilder.set_id3v1(&tag); + } + if let Some(tag) = mpeg.id3v2_tag() { + jbuilder.set_id3v2(&tag); + } + } + if let Some(mp4) = file.as_mp4() { + jbuilder.set_mime_type("audio/mp4"); + if let Some(tag) = mp4.tag() { + jbuilder.set_mp4(&tag); + } + } + if let Some(mut wav) = file.as_wav() { + jbuilder.set_mime_type("audio/wav"); + if let Some(tag) = wav.id3v2_tag() { + jbuilder.set_id3v2(&tag); + } + } + } + None => {} + } - // Return the title - let output = shared_env - .borrow_mut() - .new_string("title") - .expect("Couldn't create string!"); - output.into_raw() + jbuilder.build().into_raw() } diff --git a/musikr/src/main/jni/src/taglib/audioproperties.rs b/musikr/src/main/jni/src/taglib/audioproperties.rs index 1c57432da..f3730551c 100644 --- a/musikr/src/main/jni/src/taglib/audioproperties.rs +++ b/musikr/src/main/jni/src/taglib/audioproperties.rs @@ -1,6 +1,5 @@ use super::bridge::CppAudioProperties; -use super::this::{RefThis, This}; -use std::pin::Pin; +use super::this::RefThis; pub struct AudioProperties<'file_ref> { this: RefThis<'file_ref, CppAudioProperties>, diff --git a/musikr/src/main/jni/src/taglib/bridge.rs b/musikr/src/main/jni/src/taglib/bridge.rs index ece6a7b7e..2720bc60c 100644 --- a/musikr/src/main/jni/src/taglib/bridge.rs +++ b/musikr/src/main/jni/src/taglib/bridge.rs @@ -51,7 +51,9 @@ mod bridge_impl { #[namespace = "TagLib"] #[cxx_name = "IOStream"] type CPPIOStream<'io_stream>; - fn wrap_RsIOStream<'io_stream>(stream: Box>) -> UniquePtr>; + fn wrap_RsIOStream<'io_stream>( + stream: Box>, + ) -> UniquePtr>; #[namespace = "TagLib"] #[cxx_name = "FileRef"] @@ -207,7 +209,7 @@ mod bridge_impl { #[namespace = "taglib_shim"] fn Item_toCoverArtList(item: &CPPMP4Item) -> UniquePtr; #[namespace = "taglib_shim"] - fn Item_toLongLong(item: &CPPMP4Item) -> i64; + fn Item_toLongLong(item: &CPPMP4Item) -> i64; #[namespace = "taglib_shim"] #[cxx_name = "IntPair"] @@ -258,9 +260,7 @@ mod bridge_impl { #[cxx_name = "FrameList"] type CPPID3v2FrameList; #[namespace = "taglib_shim"] - fn FrameList_to_vector( - list: &CPPID3v2FrameList, - ) -> UniquePtr>; + fn FrameList_to_vector(list: &CPPID3v2FrameList) -> UniquePtr>; #[namespace = "taglib_shim"] #[cxx_name = "FramePointer"] @@ -318,9 +318,7 @@ mod bridge_impl { #[cxx_name = "StringList"] type CPPStringList; #[namespace = "taglib_shim"] - fn StringList_to_vector( - string_list: &CPPStringList, - ) -> UniquePtr>; + fn StringList_to_vector(string_list: &CPPStringList) -> UniquePtr>; #[namespace = "TagLib"] #[cxx_name = "ByteVector"] @@ -332,7 +330,9 @@ mod bridge_impl { #[cxx_name = "ByteVectorList"] type CPPByteVectorList; #[namespace = "taglib_shim"] - fn ByteVectorList_to_vector(list: &CPPByteVectorList) -> UniquePtr>; + fn ByteVectorList_to_vector( + list: &CPPByteVectorList, + ) -> UniquePtr>; } } @@ -437,4 +437,4 @@ impl TagLibShared for CPPByteVectorList {} impl TagLibShared for CPPCoverArtList {} impl TagLibRef for T {} -impl TagLibAllocated for T {} \ No newline at end of file +impl TagLibAllocated for T {} diff --git a/musikr/src/main/jni/src/taglib/file.rs b/musikr/src/main/jni/src/taglib/file.rs index 0670c3067..f37039f3f 100644 --- a/musikr/src/main/jni/src/taglib/file.rs +++ b/musikr/src/main/jni/src/taglib/file.rs @@ -1,16 +1,15 @@ use super::audioproperties::AudioProperties; -use super::bridge::{self, CPPFile, CPPMPEGFile}; +use super::bridge::{self, CPPFile}; use super::flac::FLACFile; -use super::id3v2::ID3v2Tag; use super::mp4::MP4File; use super::mpeg::MPEGFile; use super::ogg::OpusFile; use super::ogg::VorbisFile; -use super::this::{RefThisMut, RefThis, This, ThisMut}; -use std::pin::Pin; +use super::riff::WAVFile; +use super::this::{RefThis, RefThisMut}; pub struct File<'file_ref> { - this: RefThisMut<'file_ref, CPPFile> + this: RefThisMut<'file_ref, CPPFile>, } impl<'file_ref> File<'file_ref> { @@ -118,12 +117,16 @@ impl<'file_ref> File<'file_ref> { } pub fn as_mp4(&mut self) -> Option> { - let mp4_file = unsafe { - bridge::File_asMP4(self.this.ptr_mut()) - }; + let mp4_file = unsafe { bridge::File_asMP4(self.this.ptr_mut()) }; let mp4_ref = unsafe { mp4_file.as_mut() }; let mp4_this = mp4_ref.map(|mp4| RefThisMut::new(mp4)); mp4_this.map(|this| MP4File::new(this)) } - + + pub fn as_wav(&mut self) -> Option> { + let wav_file = unsafe { bridge::File_asWAV(self.this.ptr_mut()) }; + let wav_ref = unsafe { wav_file.as_mut() }; + let wav_this = wav_ref.map(|wav| RefThisMut::new(wav)); + wav_this.map(|this| WAVFile::new(this)) + } } diff --git a/musikr/src/main/jni/src/taglib/flac.rs b/musikr/src/main/jni/src/taglib/flac.rs index 860817182..ccf88acd1 100644 --- a/musikr/src/main/jni/src/taglib/flac.rs +++ b/musikr/src/main/jni/src/taglib/flac.rs @@ -1,17 +1,16 @@ pub use super::bridge::CPPFLACFile; pub use super::bridge::CPPFLACPicture; -use super::bridge::{CPPPictureList, FLACFile_pictureList, PictureList_to_vector, Picture_data, CPPByteVector}; +use super::bridge::{ + CPPPictureList, FLACFile_pictureList, PictureList_to_vector, Picture_data, +}; use super::id3v1::ID3v1Tag; use super::id3v2::ID3v2Tag; +use super::this::{OwnedThis, RefThis, RefThisMut, ThisMut}; use super::tk::{ByteVector, OwnedByteVector}; pub use super::xiph::XiphComment; -use super::this::{OwnedThis, RefThisMut, RefThis, This, ThisMut}; -use cxx::UniquePtr; -use std::marker::PhantomData; -use std::pin::Pin; pub struct FLACFile<'file_ref> { - this: RefThisMut<'file_ref, CPPFLACFile> + this: RefThisMut<'file_ref, CPPFLACFile>, } impl<'file_ref> FLACFile<'file_ref> { @@ -19,7 +18,6 @@ impl<'file_ref> FLACFile<'file_ref> { Self { this } } - pub fn xiph_comments(&mut self) -> Option> { let tag = self.this.pin_mut().xiphComment(false); let tag_ref = unsafe { diff --git a/musikr/src/main/jni/src/taglib/id3v1.rs b/musikr/src/main/jni/src/taglib/id3v1.rs index 91cf0b068..51f88149a 100644 --- a/musikr/src/main/jni/src/taglib/id3v1.rs +++ b/musikr/src/main/jni/src/taglib/id3v1.rs @@ -1,6 +1,6 @@ use super::bridge::{self, CPPID3v1Tag}; -use super::this::{RefThisMut, RefThis, This, OwnedThis}; -use super::tk::{String, OwnedString}; +use super::this::{OwnedThis, RefThisMut}; +use super::tk::{OwnedString, String}; pub struct ID3v1Tag<'file_ref> { this: RefThisMut<'file_ref, CPPID3v1Tag>, @@ -46,4 +46,4 @@ impl<'file_ref> ID3v1Tag<'file_ref> { pub fn track(&self) -> u32 { bridge::ID3v1Tag_track(self.this.as_ref()) } -} \ No newline at end of file +} diff --git a/musikr/src/main/jni/src/taglib/id3v2.rs b/musikr/src/main/jni/src/taglib/id3v2.rs index 97d554a69..0b5d338b2 100644 --- a/musikr/src/main/jni/src/taglib/id3v2.rs +++ b/musikr/src/main/jni/src/taglib/id3v2.rs @@ -1,13 +1,13 @@ use super::bridge::{ - self, CPPID3v2AttachedPictureFrame, CPPID3v2Frame, CPPID3v2FrameList, CPPID3v2Tag, - CPPID3v2TextIdentificationFrame, CPPID3v2UserTextIdentificationFrame, CPPStringList, CPPByteVector, + self, CPPID3v2AttachedPictureFrame, CPPID3v2Frame, CPPID3v2FrameList, + CPPID3v2Tag, CPPID3v2TextIdentificationFrame, CPPID3v2UserTextIdentificationFrame, }; -use super::tk::{self, ByteVector, StringList, OwnedByteVector, OwnedStringList}; -use super::this::{OwnedThis, RefThisMut, RefThis, This}; +use super::this::{OwnedThis, RefThis, RefThisMut}; +use super::tk::{self, ByteVector, OwnedByteVector, OwnedStringList, StringList}; pub struct ID3v2Tag<'file_ref> { this: RefThisMut<'file_ref, CPPID3v2Tag>, -} +} impl<'file_ref> ID3v2Tag<'file_ref> { pub(super) fn new(this: RefThisMut<'file_ref, CPPID3v2Tag>) -> Self { diff --git a/musikr/src/main/jni/src/taglib/iostream.rs b/musikr/src/main/jni/src/taglib/iostream.rs index 37b38f31f..6a495a6d1 100644 --- a/musikr/src/main/jni/src/taglib/iostream.rs +++ b/musikr/src/main/jni/src/taglib/iostream.rs @@ -1,7 +1,6 @@ use super::bridge::{self, CPPIOStream}; use cxx::UniquePtr; -use std::io::{Read, Seek, SeekFrom, Write}; -use std::pin::Pin; +use std::io::{Seek, SeekFrom}; pub trait IOStream { fn read_block(&mut self, buffer: &mut [u8]) -> usize; @@ -22,9 +21,7 @@ impl<'io_stream> BridgedIOStream<'io_stream> { pub fn new(stream: T) -> Self { let rs_stream: Box> = Box::new(DynIOStream(Box::new(stream))); let cpp_stream: UniquePtr> = bridge::wrap_RsIOStream(rs_stream); - BridgedIOStream { - cpp_stream, - } + BridgedIOStream { cpp_stream } } pub fn cpp_stream(&self) -> &UniquePtr { diff --git a/musikr/src/main/jni/src/taglib/mod.rs b/musikr/src/main/jni/src/taglib/mod.rs index 9315d4225..b048b1d82 100644 --- a/musikr/src/main/jni/src/taglib/mod.rs +++ b/musikr/src/main/jni/src/taglib/mod.rs @@ -1,15 +1,15 @@ -mod bridge; -mod this; -pub mod iostream; -pub mod file_ref; -pub mod file; pub mod audioproperties; -pub mod ogg; -pub mod mpeg; +mod bridge; +pub mod file; +pub mod file_ref; pub mod flac; -pub mod xiph; -pub mod tk; -pub mod id3v2; pub mod id3v1; +pub mod id3v2; +pub mod iostream; pub mod mp4; -pub mod riff; \ No newline at end of file +pub mod mpeg; +pub mod ogg; +pub mod riff; +mod this; +pub mod tk; +pub mod xiph; diff --git a/musikr/src/main/jni/src/taglib/mp4.rs b/musikr/src/main/jni/src/taglib/mp4.rs index 377c110d4..d86caa097 100644 --- a/musikr/src/main/jni/src/taglib/mp4.rs +++ b/musikr/src/main/jni/src/taglib/mp4.rs @@ -1,9 +1,11 @@ pub use super::bridge::CPPMP4Tag; -use super::bridge::{CPPFile, CPPIntPair, CPPItemMap, CPPItemMapEntry, CPPMP4File, CPPMP4Item, ItemMap_to_entries, MP4ItemType}; +use super::bridge::{ + CPPIntPair, CPPItemMap, CPPMP4File, CPPMP4Item, ItemMap_to_entries, + MP4ItemType, +}; +use super::this::{OwnedThis, RefThis, RefThisMut}; use super::tk; -use super::this::{OwnedThis, RefThis, RefThisMut, ThisMut, This}; use std::collections::HashMap; -use std::pin::Pin; pub struct MP4File<'file_ref> { this: RefThisMut<'file_ref, CPPMP4File>, @@ -42,7 +44,7 @@ impl<'file_ref> MP4Tag<'file_ref> { } } -pub struct ItemMap<'file_ref> { +pub struct ItemMap<'file_ref> { this: RefThis<'file_ref, CPPItemMap>, } @@ -53,8 +55,8 @@ impl<'file_ref> ItemMap<'file_ref> { pub fn to_hashmap(&self) -> HashMap> { let cxx_vec = ItemMap_to_entries(self.this.as_ref()); - let vec: Vec<(String, MP4Item<'file_ref>)> = - cxx_vec.iter() + let vec: Vec<(String, MP4Item<'file_ref>)> = cxx_vec + .iter() .map(|property| { // SAFETY: // - This pin is only used in this unsafe scope. @@ -65,11 +67,11 @@ impl<'file_ref> ItemMap<'file_ref> { let key_ref = property.key(); let key_this = OwnedThis::new(key_ref).unwrap(); let key = tk::String::new(key_this).to_string(); - + let value_ref = property.value(); let value_this = OwnedThis::new(value_ref).unwrap(); let value = MP4Item::new(value_this); - + (key, value) }) .collect(); @@ -101,24 +103,30 @@ impl<'file_ref> MP4Item<'file_ref> { let pair = super::bridge::Item_toIntPair(self.this.as_ref()); let pair_this = OwnedThis::new(pair).unwrap(); Some(MP4Data::IntPair(IntPair::new(pair_this))) - }, + } MP4ItemType::Byte => Some(MP4Data::Byte(self.this.as_ref().toByte())), MP4ItemType::UInt => Some(MP4Data::UInt(self.this.as_ref().toUInt())), - MP4ItemType::LongLong => Some(MP4Data::LongLong(super::bridge::Item_toLongLong(self.this.as_ref()))), + MP4ItemType::LongLong => Some(MP4Data::LongLong(super::bridge::Item_toLongLong( + self.this.as_ref(), + ))), MP4ItemType::StringList => { let string_list = super::bridge::Item_toStringList(self.this.as_ref()); let string_list_this = OwnedThis::new(string_list).unwrap(); Some(MP4Data::StringList(tk::StringList::new(string_list_this))) - }, + } MP4ItemType::ByteVectorList => { let byte_vector_list = super::bridge::Item_toByteVectorList(self.this.as_ref()); let byte_vector_list_this = OwnedThis::new(byte_vector_list).unwrap(); - Some(MP4Data::ByteVectorList(tk::ByteVectorList::new(byte_vector_list_this))) - }, + Some(MP4Data::ByteVectorList(tk::ByteVectorList::new( + byte_vector_list_this, + ))) + } MP4ItemType::CoverArtList => { let cover_art_list = super::bridge::Item_toCoverArtList(self.this.as_ref()); let cover_art_list_this = OwnedThis::new(cover_art_list).unwrap(); - Some(MP4Data::CoverArtList(CoverArtList::new(cover_art_list_this))) + Some(MP4Data::CoverArtList(CoverArtList::new( + cover_art_list_this, + ))) } }) } diff --git a/musikr/src/main/jni/src/taglib/mpeg.rs b/musikr/src/main/jni/src/taglib/mpeg.rs index c17cebd90..8102e43a5 100644 --- a/musikr/src/main/jni/src/taglib/mpeg.rs +++ b/musikr/src/main/jni/src/taglib/mpeg.rs @@ -1,8 +1,7 @@ -use super::bridge::{self, CPPMPEGFile}; +use super::bridge::{CPPMPEGFile}; use super::id3v1::ID3v1Tag; use super::id3v2::ID3v2Tag; -use super::this::{RefThisMut, This, ThisMut}; -use std::pin::Pin; +use super::this::{RefThisMut, ThisMut}; pub struct MPEGFile<'file_ref> { this: RefThisMut<'file_ref, CPPMPEGFile>, diff --git a/musikr/src/main/jni/src/taglib/ogg.rs b/musikr/src/main/jni/src/taglib/ogg.rs index 4d9ee5262..b82b00c1f 100644 --- a/musikr/src/main/jni/src/taglib/ogg.rs +++ b/musikr/src/main/jni/src/taglib/ogg.rs @@ -1,7 +1,6 @@ pub use super::bridge::{CPPOpusFile, CPPVorbisFile}; +use super::this::RefThisMut; use super::xiph::XiphComment; -use super::this::{RefThisMut, RefThis, This}; -use std::pin::Pin; pub struct VorbisFile<'file_ref> { this: RefThisMut<'file_ref, CPPVorbisFile>, diff --git a/musikr/src/main/jni/src/taglib/riff.rs b/musikr/src/main/jni/src/taglib/riff.rs index d2640d683..315c762b0 100644 --- a/musikr/src/main/jni/src/taglib/riff.rs +++ b/musikr/src/main/jni/src/taglib/riff.rs @@ -1,7 +1,6 @@ -use super::bridge::{self, CPPWAVFile}; +use super::bridge::{CPPWAVFile}; use super::id3v2::ID3v2Tag; -use super::this::{RefThisMut, This, ThisMut}; -use std::pin::Pin; +use super::this::RefThisMut; pub struct WAVFile<'file_ref> { this: RefThisMut<'file_ref, CPPWAVFile>, @@ -18,4 +17,4 @@ impl<'file_ref> WAVFile<'file_ref> { let tag_this = tag_ref.map(|tag| RefThisMut::new(tag)); tag_this.map(|this| ID3v2Tag::new(this)) } -} \ No newline at end of file +} diff --git a/musikr/src/main/jni/src/taglib/this.rs b/musikr/src/main/jni/src/taglib/this.rs index d7c4ffc13..2c027cdb2 100644 --- a/musikr/src/main/jni/src/taglib/this.rs +++ b/musikr/src/main/jni/src/taglib/this.rs @@ -1,7 +1,7 @@ +use super::bridge::{TagLibAllocated, TagLibRef, TagLibShared}; +use cxx::{memory::UniquePtrTarget, UniquePtr}; use std::marker::PhantomData; use std::pin::Pin; -use cxx::{UniquePtr, memory::UniquePtrTarget}; -use super::bridge::{TagLibAllocated, TagLibRef, TagLibShared}; /// A taglib-FFI-specific trait representing a C++ object returned by the library. /// @@ -10,7 +10,7 @@ use super::bridge::{TagLibAllocated, TagLibRef, TagLibShared}; /// and will be dropped when the FileRef is dropped. /// - This object will not move or be mutated over the FileRef's lifetime, this way /// it can be temporarily pinned for use as a `this` pointer. -pub trait This<'file_ref, T: TagLibAllocated> : AsRef {} +pub trait This<'file_ref, T: TagLibAllocated>: AsRef {} /// A taglib-FFI-specific trait representing a C++ object returned by the library. /// @@ -22,18 +22,18 @@ pub trait This<'file_ref, T: TagLibAllocated> : AsRef {} /// and will be dropped when the FileRef is dropped. /// - This object will not move over the FileRef's lifetime, this way it can be /// temporarily pinned for use as a `this` pointer. -pub trait ThisMut<'file_ref, T: TagLibAllocated> : This<'file_ref, T> { +pub trait ThisMut<'file_ref, T: TagLibAllocated>: This<'file_ref, T> { fn pin_mut(&mut self) -> Pin<&mut T>; } /// A [This] instance that is a reference to a C++ object. pub struct RefThis<'file_ref, T: TagLibRef> { - this: &'file_ref T + this: &'file_ref T, } impl<'file_ref, T: TagLibRef> RefThis<'file_ref, T> { /// Create a new [RefThis] from a reference to a C++ object. - /// + /// /// This is safe to call assuming the contract of [This] is upheld. Since this /// contract cannot be enforced by the Rust compiler, it is the caller's /// responsibility to ensure that the reference is valid for the lifetime of @@ -46,7 +46,7 @@ impl<'file_ref, T: TagLibRef> RefThis<'file_ref, T> { } /// Get a pointer to the C++ object. - /// + /// /// This can be used to pass the object to FFI functions that take a pointer. /// /// This is safe to call assuming the contract of [This] is upheld. @@ -64,7 +64,7 @@ impl<'file_ref, T: TagLibRef> AsRef for RefThis<'file_ref, T> { impl<'file_ref, T: TagLibRef> This<'file_ref, T> for RefThis<'file_ref, T> {} /// A [ThisMut] instance that is a reference to a C++ object. -/// +/// /// This is similar to [RefThis], but allows mutating the object. pub struct RefThisMut<'file_ref, T: TagLibRef> { this: &'file_ref mut T, @@ -72,7 +72,7 @@ pub struct RefThisMut<'file_ref, T: TagLibRef> { impl<'file_ref, T: TagLibRef> RefThisMut<'file_ref, T> { /// Create a new [RefThisMut] from a reference to a C++ object. - /// + /// /// This is safe to call assuming the contract of [ThisMut] is upheld. Since /// this contract cannot be enforced by the Rust compiler, it is the caller's /// responsibility to ensure that the reference is valid for the lifetime of @@ -83,18 +83,18 @@ impl<'file_ref, T: TagLibRef> RefThisMut<'file_ref, T> { } /// Get a pointer to the C++ object. - /// + /// /// This can be used to pass the object to FFI functions that take a pointer. - /// + /// /// This is safe to call assuming the contract of [ThisMut] is upheld. pub fn ptr(&self) -> *const T { self.this as *const T } /// Get a pointer to the C++ object. - /// + /// /// This can be used to pass the object to FFI functions that take a pointer. - /// + /// /// This is safe to call assuming the contract of [ThisMut] is upheld. pub fn ptr_mut(&mut self) -> *mut T { self.this as *mut T @@ -116,7 +116,7 @@ impl<'file_ref, T: TagLibRef> ThisMut<'file_ref, T> for RefThisMut<'file_ref, T> } /// A [This] instance that is "owned" by the caller. -/// +/// /// "Owned" in this context only really means that the object is not a rust reference. /// In practice, all "owned" taglib objects are actually shared references, and are /// thus tied to the lifetime of the `'file_ref` parameter. @@ -127,13 +127,13 @@ pub struct OwnedThis<'file_ref, T: TagLibShared + UniquePtrTarget> { impl<'file_ref, T: TagLibShared + UniquePtrTarget> OwnedThis<'file_ref, T> { /// Create a new [OwnedThis] from a [UniquePtr]. - /// + /// /// This is safe to call assuming the contract of [This] is upheld. Since this /// contract cannot be enforced by the Rust compiler, it is the caller's /// responsibility to ensure that the `UniquePtr` is valid for the lifetime of /// the `'file_ref` parameter. More or less, if it comes from the TagLib FFI /// interface, it is safe to use this. - /// + /// /// This will return `None` if the `UniquePtr` is `null`. pub fn new(this: UniquePtr) -> Option { if !this.is_null() { @@ -155,9 +155,10 @@ impl<'file_ref, T: TagLibShared + UniquePtrTarget> AsRef for OwnedThis<'file_ impl<'file_ref, T: TagLibShared + UniquePtrTarget> This<'file_ref, T> for OwnedThis<'file_ref, T> {} -impl<'file_ref, T: TagLibShared + UniquePtrTarget> ThisMut<'file_ref, T> for OwnedThis<'file_ref, T> { +impl<'file_ref, T: TagLibShared + UniquePtrTarget> ThisMut<'file_ref, T> + for OwnedThis<'file_ref, T> +{ fn pin_mut(&mut self) -> Pin<&mut T> { self.this.as_mut().unwrap() } } - diff --git a/musikr/src/main/jni/src/taglib/tk.rs b/musikr/src/main/jni/src/taglib/tk.rs index 73ed14683..779abce5c 100644 --- a/musikr/src/main/jni/src/taglib/tk.rs +++ b/musikr/src/main/jni/src/taglib/tk.rs @@ -1,14 +1,12 @@ use super::bridge; -use super::this::{RefThis, RefThisMut, This, OwnedThis}; -use cxx::{memory::UniquePtrTarget, UniquePtr}; +use super::this::{OwnedThis, RefThis, RefThisMut, This}; use std::marker::PhantomData; -use std::pin::Pin; use std::{ffi::CStr, string::ToString}; -pub use bridge::CPPString as InnerString; -pub use bridge::CPPStringList as InnerStringList; pub use bridge::CPPByteVector as InnerByteVector; pub use bridge::CPPByteVectorList as InnerByteVectorList; +pub use bridge::CPPString as InnerString; +pub use bridge::CPPStringList as InnerStringList; pub struct String<'file_ref, T: This<'file_ref, InnerString>> { _data: PhantomData<&'file_ref ()>, @@ -17,7 +15,10 @@ pub struct String<'file_ref, T: This<'file_ref, InnerString>> { impl<'file_ref, T: This<'file_ref, InnerString>> String<'file_ref, T> { pub(super) fn new(this: T) -> Self { - Self { _data: PhantomData, this } + Self { + _data: PhantomData, + this, + } } } @@ -49,13 +50,12 @@ pub struct StringList<'file_ref, T: This<'file_ref, InnerStringList>> { this: T, } -pub type OwnedStringList<'file_ref> = StringList<'file_ref, OwnedThis<'file_ref, InnerStringList>>; -pub type RefStringList<'file_ref> = StringList<'file_ref, RefThis<'file_ref, InnerStringList>>; -pub type RefStringListMut<'file_ref> = StringList<'file_ref, RefThisMut<'file_ref, InnerStringList>>; - impl<'file_ref, T: This<'file_ref, InnerStringList>> StringList<'file_ref, T> { pub(super) fn new(this: T) -> Self { - Self { _data: PhantomData, this } + Self { + _data: PhantomData, + this, + } } pub fn to_vec(&self) -> Vec { @@ -70,6 +70,11 @@ impl<'file_ref, T: This<'file_ref, InnerStringList>> StringList<'file_ref, T> { } } +pub type OwnedStringList<'file_ref> = StringList<'file_ref, OwnedThis<'file_ref, InnerStringList>>; +pub type RefStringList<'file_ref> = StringList<'file_ref, RefThis<'file_ref, InnerStringList>>; +pub type RefStringListMut<'file_ref> = + StringList<'file_ref, RefThisMut<'file_ref, InnerStringList>>; + pub struct ByteVector<'file_ref, T: This<'file_ref, InnerByteVector>> { _data: PhantomData<&'file_ref InnerByteVector>, this: T, @@ -77,7 +82,10 @@ pub struct ByteVector<'file_ref, T: This<'file_ref, InnerByteVector>> { impl<'file_ref, T: This<'file_ref, InnerByteVector>> ByteVector<'file_ref, T> { pub(super) fn new(this: T) -> Self { - Self { _data: PhantomData, this } + Self { + _data: PhantomData, + this, + } } pub fn to_vec(&self) -> Vec { @@ -107,7 +115,8 @@ impl<'file_ref, T: This<'file_ref, InnerByteVector>> ByteVector<'file_ref, T> { pub type OwnedByteVector<'file_ref> = ByteVector<'file_ref, OwnedThis<'file_ref, InnerByteVector>>; pub type RefByteVector<'file_ref> = ByteVector<'file_ref, RefThis<'file_ref, InnerByteVector>>; -pub type RefByteVectorMut<'file_ref> = ByteVector<'file_ref, RefThisMut<'file_ref, InnerByteVector>>; +pub type RefByteVectorMut<'file_ref> = + ByteVector<'file_ref, RefThisMut<'file_ref, InnerByteVector>>; pub struct ByteVectorList<'file_ref, T: This<'file_ref, InnerByteVectorList>> { _data: PhantomData<&'file_ref InnerByteVectorList>, @@ -116,7 +125,10 @@ pub struct ByteVectorList<'file_ref, T: This<'file_ref, InnerByteVectorList>> { impl<'file_ref, T: This<'file_ref, InnerByteVectorList>> ByteVectorList<'file_ref, T> { pub(super) fn new(this: T) -> Self { - Self { _data: PhantomData, this } + Self { + _data: PhantomData, + this, + } } pub fn to_vec(&self) -> Vec> { @@ -128,7 +140,9 @@ impl<'file_ref, T: This<'file_ref, InnerByteVectorList>> ByteVectorList<'file_re } } -pub type OwnedByteVectorList<'file_ref> = ByteVectorList<'file_ref, OwnedThis<'file_ref, InnerByteVectorList>>; -pub type RefByteVectorList<'file_ref> = ByteVectorList<'file_ref, RefThis<'file_ref, InnerByteVectorList>>; -pub type RefByteVectorListMut<'file_ref> = ByteVectorList<'file_ref, RefThisMut<'file_ref, InnerByteVectorList>>; - +pub type OwnedByteVectorList<'file_ref> = + ByteVectorList<'file_ref, OwnedThis<'file_ref, InnerByteVectorList>>; +pub type RefByteVectorList<'file_ref> = + ByteVectorList<'file_ref, RefThis<'file_ref, InnerByteVectorList>>; +pub type RefByteVectorListMut<'file_ref> = + ByteVectorList<'file_ref, RefThisMut<'file_ref, InnerByteVectorList>>; diff --git a/musikr/src/main/jni/src/taglib/xiph.rs b/musikr/src/main/jni/src/taglib/xiph.rs index a9b6b0d06..8bcc0cde1 100644 --- a/musikr/src/main/jni/src/taglib/xiph.rs +++ b/musikr/src/main/jni/src/taglib/xiph.rs @@ -1,10 +1,9 @@ pub use super::bridge::CPPXiphComment; use super::bridge::{CPPFieldListMap, FieldListMap_to_entries, XiphComment_pictureList}; pub use super::flac::PictureList; +use super::this::{OwnedThis, RefThis, RefThisMut, ThisMut}; use super::tk; -use super::this::{OwnedThis, RefThis, RefThisMut, ThisMut, This}; use std::collections::HashMap; -use std::pin::Pin; pub struct XiphComment<'file_ref> { this: RefThisMut<'file_ref, CPPXiphComment>, diff --git a/musikr/src/main/jni/src/tagmap.rs b/musikr/src/main/jni/src/tagmap.rs index 023ce7e93..b466fdc3d 100644 --- a/musikr/src/main/jni/src/tagmap.rs +++ b/musikr/src/main/jni/src/tagmap.rs @@ -1,7 +1,10 @@ +use jni::{ + objects::{JObject, JValueGen}, + JNIEnv, +}; +use std::cell::RefCell; use std::collections::HashMap; use std::rc::Rc; -use std::cell::RefCell; -use jni::{objects::{JObject, JValueGen}, JNIEnv}; pub struct JTagMap<'local> { env: Rc>>, @@ -27,7 +30,12 @@ impl<'local> JTagMap<'local> { self.map.entry(id).or_default().extend(values); } - pub fn add_combined(&mut self, id: impl Into, description: impl Into, value: impl Into) { + pub fn add_combined( + &mut self, + id: impl Into, + description: impl Into, + value: impl Into, + ) { let id = id.into(); let description = description.into(); let value = value.into(); @@ -36,8 +44,16 @@ impl<'local> JTagMap<'local> { } pub fn get_object(&self) -> JObject { - let map_class = self.env.borrow_mut().find_class("java/util/HashMap").unwrap(); - let map = self.env.borrow_mut().new_object(&map_class, "()V", &[]).unwrap(); + let map_class = self + .env + .borrow_mut() + .find_class("java/util/HashMap") + .unwrap(); + let map = self + .env + .borrow_mut() + .new_object(&map_class, "()V", &[]) + .unwrap(); for (key, values) in &self.map { let j_key = self.env.borrow().new_string(key).unwrap(); @@ -45,30 +61,42 @@ impl<'local> JTagMap<'local> { .iter() .map(|v| self.env.borrow().new_string(v).unwrap().into()) .collect(); - + // Create ArrayList for values - let array_list_class = self.env.borrow_mut().find_class("java/util/ArrayList").unwrap(); - let array_list = self.env.borrow_mut().new_object(array_list_class, "()V", &[]).unwrap(); + let array_list_class = self + .env + .borrow_mut() + .find_class("java/util/ArrayList") + .unwrap(); + let array_list = self + .env + .borrow_mut() + .new_object(array_list_class, "()V", &[]) + .unwrap(); for value in j_values { - self.env.borrow_mut() + self.env + .borrow_mut() .call_method( &array_list, "add", "(Ljava/lang/Object;)Z", - &[JValueGen::from(&value)] - ).unwrap(); + &[JValueGen::from(&value)], + ) + .unwrap(); } - self.env.borrow_mut() + self.env + .borrow_mut() .call_method( &map, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", - &[JValueGen::from(&j_key), JValueGen::from(&array_list)] - ).unwrap(); + &[JValueGen::from(&j_key), JValueGen::from(&array_list)], + ) + .unwrap(); } map } -} \ No newline at end of file +}