LCOV - code coverage report
Current view: top level - src/sources - file_media_source.dart Coverage Total Hit
Test: lcov.info Lines: 51.6 % 157 81
Test Date: 2025-11-06 04:39:56

            Line data    Source code
       1              : import 'package:cross_file/cross_file.dart';
       2              : import 'package:media_source/src/media_type.dart';
       3              : import 'package:media_source/src/sources/media_source.dart';
       4              : import 'package:media_source/src/sources/memory_media_source.dart';
       5              : import 'package:media_source/src/extensions/file_extensions.dart';
       6              : import 'package:media_source/src/utils/platform_utils.dart';
       7              : import 'package:path/path.dart' as p;
       8              : import 'package:file_sized/file_sized.dart';
       9              : import 'package:file_type_plus/file_type_plus.dart';
      10              : 
      11              : /// Abstract base class for file-based media sources.
      12              : ///
      13              : /// This class manages media content stored on the file system. It provides:
      14              : /// - File I/O operations (save, move, delete)
      15              : /// - Type-specific file media implementations
      16              : /// - Conversion to in-memory representation
      17              : /// - Factory methods for creating instances from file paths or XFile objects
      18              : ///
      19              : /// Subclasses include:
      20              : /// - [VideoFileMedia] for video files
      21              : /// - [AudioFileMedia] for audio files
      22              : /// - [ImageFileMedia] for image files
      23              : /// - [DocumentFileMedia] for document files
      24              : /// - [OtherTypeFileMedia] for unclassified files
      25              : abstract class FileMediaSource<M extends FileType> extends MediaSource<M> implements ToMemoryConvertableMedia<M> {
      26              :   /// The underlying cross-platform file object.
      27              :   final XFile file;
      28              : 
      29              :   /// Internal constructor for creating file media sources.
      30              :   ///
      31              :   /// Parameters:
      32              :   /// - [file]: The XFile representing the media file
      33              :   /// - [metadata]: Type-specific metadata (VideoType, AudioType, etc.)
      34              :   /// - [name]: Optional custom name, defaults to file name
      35              :   /// - [size]: Optional file size, auto-detected if not provided
      36              :   /// - [mimeType]: Optional MIME type, auto-detected if not provided
      37            1 :   FileMediaSource._({
      38              :     required this.file,
      39              :     required super.metadata,
      40              :     required String? name,
      41              :     required super.size,
      42              :     required String? mimeType,
      43            1 :   }) : super(
      44            0 :           mimeType: mimeType ?? file.mimeType ?? FileUtil.getMimeTypeFromPath(file.path),
      45            0 :           name: name ?? file.name,
      46              :         );
      47              : 
      48              :   /// Saves this media to the specified file path.
      49              :   ///
      50              :   /// Returns a new [FileMediaSource] instance pointing to the saved file.
      51              :   /// Subclasses implement specific type handling.
      52              :   Future<FileMediaSource<M>> saveTo(String path);
      53              : 
      54              :   /// Saves this media to a folder, preserving the original filename.
      55              :   ///
      56              :   /// Parameters:
      57              :   /// - [folderPath]: The directory where the file should be saved
      58              :   ///
      59              :   /// Returns a new [FileMediaSource] instance with the file in the folder.
      60            0 :   Future<FileMediaSource<M>> saveToFolder(String folderPath) => saveTo(p.join(folderPath, name));
      61              : 
      62              :   /// Moves this media to a new file path.
      63              :   ///
      64              :   /// If the destination already exists, it will be deleted before moving.
      65              :   /// Returns early if the source path matches the destination.
      66              :   ///
      67              :   /// Parameters:
      68              :   /// - [path]: The destination file path
      69              :   ///
      70              :   /// Returns a new [FileMediaSource] instance at the new location.
      71            0 :   Future<FileMediaSource<M>> moveTo(String path) async {
      72            0 :     if (file.path == path) return this;
      73            0 :     final newPathFile = XFile(path);
      74            0 :     if (await newPathFile.exists()) {
      75            0 :       await newPathFile.delete();
      76              :     }
      77            0 :     final saved = await saveTo(path);
      78            0 :     await delete();
      79              :     return saved;
      80              :   }
      81              : 
      82              :   /// Moves this media to a folder, preserving the original filename.
      83              :   ///
      84              :   /// Parameters:
      85              :   /// - [folderPath]: The directory where the file should be moved
      86              :   ///
      87              :   /// Returns a new [FileMediaSource] instance with the file in the folder.
      88            0 :   Future<FileMediaSource<M>> moveToFolder(String folderPath) => moveTo(p.join(folderPath, name));
      89              : 
      90              :   /// Deletes the file from the file system.
      91              :   ///
      92              :   /// Returns true if deletion was successful, false otherwise.
      93            0 :   Future<bool> delete() => file.delete();
      94              : 
      95              :   /// Creates a [FileMediaSource] from a file path.
      96              :   ///
      97              :   /// Automatically detects the media type and returns the appropriate subclass.
      98              :   /// If media type is not provided, it will be determined from the file.
      99              :   ///
     100              :   /// Parameters:
     101              :   /// - [path]: The file system path to the media file
     102              :   /// - [name]: Optional custom display name
     103              :   /// - [size]: Optional pre-computed file size
     104              :   /// - [mimeType]: Optional MIME type
     105              :   /// - [duration]: Optional duration for audio/video files
     106              :   /// - [mediaType]: Optional explicit media type (for type narrowing)
     107              :   ///
     108              :   /// Returns the appropriate [FileMediaSource] subclass based on media type.
     109            0 :   static Future<FileMediaSource> fromPath(
     110              :     String path, {
     111              :     String? name,
     112              :     FileSize? size,
     113              :     String? mimeType,
     114              :     Duration? duration,
     115              :     FileType? mediaType,
     116              :   }) =>
     117            0 :       fromFile(
     118            0 :         XFile(
     119              :           path,
     120              :           mimeType: mimeType,
     121            0 :           length: size?.inBytes,
     122              :           name: name,
     123              :         ),
     124              :         name: name,
     125              :         mimeType: mimeType,
     126              :         duration: duration,
     127              :         mediaType: mediaType,
     128              :         size: size,
     129              :       );
     130              : 
     131              :   /// Creates a [FileMediaSource] from an XFile object.
     132              :   ///
     133              :   /// Automatically detects the media type and returns the appropriate subclass.
     134              :   /// Supports:
     135              :   /// - [AudioFileMedia] for audio files
     136              :   /// - [VideoFileMedia] for video files
     137              :   /// - [ImageFileMedia] for image files
     138              :   /// - [DocumentFileMedia] for document files
     139              :   /// - [OtherTypeFileMedia] for unclassified files
     140              :   ///
     141              :   /// Parameters:
     142              :   /// - [file]: The XFile object representing the media
     143              :   /// - [name]: Optional custom display name
     144              :   /// - [mimeType]: Optional MIME type override
     145              :   /// - [duration]: Optional duration for audio/video files
     146              :   /// - [mediaType]: Optional explicit media type
     147              :   /// - [size]: Optional pre-computed file size
     148              :   ///
     149              :   /// Returns the appropriate [FileMediaSource] subclass.
     150            0 :   static Future<FileMediaSource> fromFile(
     151              :     XFile file, {
     152              :     String? name,
     153              :     String? mimeType,
     154              :     Duration? duration,
     155              :     FileType? mediaType,
     156              :     FileSize? size,
     157              :   }) async {
     158            0 :     mediaType ??= await file.getMediaType(mimeType);
     159            0 :     if (mediaType.isAny([FileType.audio])) {
     160            0 :       return AudioFileMedia.fromFile(
     161              :         file,
     162              :         name: name,
     163              :         duration: duration,
     164              :         mimeType: mimeType,
     165              :         size: size,
     166              :       );
     167              :     }
     168            0 :     if (mediaType.isAny([FileType.video])) {
     169            0 :       return VideoFileMedia.fromFile(
     170              :         file,
     171              :         name: name,
     172              :         duration: duration,
     173              :         mimeType: mimeType,
     174              :         size: size,
     175              :       );
     176              :     }
     177            0 :     if (mediaType.isAny([FileType.image])) {
     178            0 :       return ImageFileMedia.fromFile(
     179              :         file,
     180              :         name: name,
     181              :         mimeType: mimeType,
     182              :         size: size,
     183              :       );
     184              :     }
     185            0 :     if (mediaType.isAny([FileType.document])) {
     186            0 :       return DocumentFileMedia.fromFile(
     187              :         file,
     188              :         name: name,
     189              :         mimeType: mimeType,
     190              :         size: size,
     191              :       );
     192              :     }
     193            0 :     return OtherTypeFileMedia.fromFile(
     194              :       file,
     195              :       name: name,
     196              :       mimeType: mimeType,
     197              :       size: size,
     198              :     );
     199              :   }
     200              : 
     201              :   /// Includes the file object in equality comparisons.
     202            0 :   @override
     203            0 :   List<Object?> get props => [file, ...super.props];
     204              : }
     205              : 
     206              : /// Represents video files stored on the file system.
     207              : ///
     208              : /// Stores video metadata including optional duration information.
     209              : /// Supports saving, moving, deleting, and conversion to in-memory representation.
     210              : class VideoFileMedia extends FileMediaSource<VideoType> {
     211              :   /// Internal constructor for creating video file media.
     212              :   ///
     213              :   /// Parameters:
     214              :   /// - [file]: The video file
     215              :   /// - [name]: Display name
     216              :   /// - [duration]: Optional video duration
     217              :   /// - [size]: File size
     218              :   /// - [mimeType]: MIME type of the video
     219            1 :   VideoFileMedia._({
     220              :     required super.file,
     221              :     required super.name,
     222              :     required Duration? duration,
     223              :     required super.size,
     224              :     required super.mimeType,
     225            2 :   }) : super._(metadata: VideoType(duration));
     226              : 
     227              :   /// Creates a [VideoFileMedia] from a file path.
     228              :   ///
     229              :   /// Parameters:
     230              :   /// - [path]: The file system path to the video
     231              :   /// - [name]: Optional custom display name
     232              :   /// - [duration]: Optional video duration
     233              :   /// - [mimeType]: Optional MIME type override
     234              :   /// - [size]: Optional pre-computed file size
     235            0 :   static Future<VideoFileMedia> fromPath(
     236              :     String path, {
     237              :     String? name,
     238              :     Duration? duration,
     239              :     String? mimeType,
     240              :     FileSize? size,
     241              :   }) async {
     242            0 :     final file = XFile(
     243              :       path,
     244              :       name: name,
     245              :       mimeType: mimeType,
     246            0 :       length: size?.inBytes,
     247              :     );
     248            0 :     return fromFile(
     249              :       file,
     250              :       name: name,
     251              :       duration: duration,
     252              :       mimeType: mimeType,
     253              :       size: size,
     254              :     );
     255              :   }
     256              : 
     257              :   /// Creates a [VideoFileMedia] from an XFile object.
     258              :   ///
     259              :   /// Parameters:
     260              :   /// - [file]: The XFile representing the video
     261              :   /// - [name]: Optional custom display name
     262              :   /// - [duration]: Optional video duration
     263              :   /// - [mimeType]: Optional MIME type override
     264              :   /// - [size]: Optional pre-computed file size, auto-detected if not provided
     265            1 :   static Future<VideoFileMedia> fromFile(
     266              :     XFile file, {
     267              :     String? name,
     268              :     Duration? duration,
     269              :     String? mimeType,
     270              :     FileSize? size,
     271              :   }) async {
     272            1 :     return VideoFileMedia._(
     273              :       file: file,
     274            0 :       size: size ?? await file.size(),
     275              :       name: name,
     276              :       duration: duration,
     277              :       mimeType: mimeType,
     278              :     );
     279              :   }
     280              : 
     281              :   /// Saves this video to the specified file path.
     282              :   ///
     283              :   /// Creates the directory if it doesn't exist, then saves the file
     284              :   /// and returns a new instance pointing to the saved location.
     285            1 :   @override
     286              :   Future<VideoFileMedia> saveTo(String path) async {
     287            2 :     await PlatformUtils.instance.createDirectoryIfNotExists(path);
     288            2 :     await file.saveTo(path);
     289            1 :     return VideoFileMedia._(
     290            1 :       file: XFile(
     291              :         path,
     292            1 :         name: name,
     293            1 :         mimeType: mimeType,
     294            2 :         length: size?.inBytes,
     295              :       ),
     296            1 :       size: size ?? await file.size(),
     297            1 :       name: name,
     298            2 :       duration: metadata.duration,
     299            1 :       mimeType: mimeType,
     300              :     );
     301              :   }
     302              : 
     303              :   /// Converts this video to an in-memory representation.
     304              :   ///
     305              :   /// Loads the entire file content into memory as a byte array.
     306              :   /// Useful for uploading or processing without file system access.
     307            0 :   @override
     308              :   Future<MemoryMediaSource<VideoType>> convertToMemory() async {
     309            0 :     return VideoMemoryMedia(
     310            0 :       await file.readAsBytes(),
     311            0 :       name: name,
     312            0 :       duration: metadata.duration,
     313            0 :       mimeType: mimeType,
     314              :     );
     315              :   }
     316              : }
     317              : 
     318              : /// Represents audio files stored on the file system.
     319              : ///
     320              : /// Stores audio metadata including optional duration information.
     321              : /// Supports saving, moving, deleting, and conversion to in-memory representation.
     322              : class AudioFileMedia extends FileMediaSource<AudioType> {
     323              :   /// Internal constructor for creating audio file media.
     324              :   ///
     325              :   /// Parameters:
     326              :   /// - [file]: The audio file
     327              :   /// - [name]: Display name
     328              :   /// - [duration]: Optional audio duration
     329              :   /// - [size]: File size
     330              :   /// - [mimeType]: MIME type of the audio
     331            1 :   AudioFileMedia._({
     332              :     required super.file,
     333              :     required super.name,
     334              :     required Duration? duration,
     335              :     required super.size,
     336              :     required super.mimeType,
     337            2 :   }) : super._(metadata: AudioType(duration));
     338              : 
     339              :   /// Creates an [AudioFileMedia] from a file path.
     340              :   ///
     341              :   /// Parameters:
     342              :   /// - [path]: The file system path to the audio file
     343              :   /// - [name]: Optional custom display name
     344              :   /// - [duration]: Optional audio duration
     345              :   /// - [mimeType]: Optional MIME type override
     346              :   /// - [size]: Optional pre-computed file size
     347            0 :   static Future<AudioFileMedia> fromPath(
     348              :     String path, {
     349              :     String? name,
     350              :     Duration? duration,
     351              :     String? mimeType,
     352              :     FileSize? size,
     353              :   }) async {
     354            0 :     final file = XFile(
     355              :       path,
     356              :       mimeType: mimeType,
     357              :       name: name,
     358            0 :       length: size?.inBytes,
     359              :     );
     360            0 :     return fromFile(
     361              :       file,
     362              :       name: name,
     363              :       duration: duration,
     364              :       mimeType: mimeType,
     365              :       size: size,
     366              :     );
     367              :   }
     368              : 
     369              :   /// Creates an [AudioFileMedia] from an XFile object.
     370              :   ///
     371              :   /// Parameters:
     372              :   /// - [file]: The XFile representing the audio
     373              :   /// - [name]: Optional custom display name
     374              :   /// - [duration]: Optional audio duration
     375              :   /// - [mimeType]: Optional MIME type override
     376              :   /// - [size]: Optional pre-computed file size, auto-detected if not provided
     377            1 :   static Future<AudioFileMedia> fromFile(
     378              :     XFile file, {
     379              :     String? name,
     380              :     Duration? duration,
     381              :     String? mimeType,
     382              :     FileSize? size,
     383              :   }) async {
     384            1 :     return AudioFileMedia._(
     385              :       file: file,
     386            0 :       size: size ?? await file.size(),
     387              :       name: name,
     388              :       duration: duration,
     389              :       mimeType: mimeType,
     390              :     );
     391              :   }
     392              : 
     393              :   /// Saves this audio to the specified file path.
     394              :   ///
     395              :   /// Creates the directory if it doesn't exist, then saves the file
     396              :   /// and returns a new instance pointing to the saved location.
     397            1 :   @override
     398              :   Future<AudioFileMedia> saveTo(String path) async {
     399            2 :     await PlatformUtils.instance.createDirectoryIfNotExists(path);
     400            2 :     await file.saveTo(path);
     401            1 :     return AudioFileMedia._(
     402            1 :       file: XFile(
     403              :         path,
     404            1 :         name: super.name,
     405            1 :         mimeType: super.mimeType,
     406            2 :         length: size?.inBytes,
     407              :       ),
     408            1 :       size: size ?? await file.size(),
     409            1 :       name: name,
     410            2 :       duration: metadata.duration,
     411            1 :       mimeType: mimeType,
     412              :     );
     413              :   }
     414              : 
     415              :   /// Converts this audio to an in-memory representation.
     416              :   ///
     417              :   /// Loads the entire file content into memory as a byte array.
     418              :   /// Useful for uploading or processing without file system access.
     419            0 :   @override
     420              :   Future<MemoryMediaSource<AudioType>> convertToMemory() async {
     421            0 :     return AudioMemoryMedia(
     422            0 :       await file.readAsBytes(),
     423            0 :       name: name,
     424            0 :       duration: metadata.duration,
     425            0 :       mimeType: mimeType,
     426              :     );
     427              :   }
     428              : }
     429              : 
     430              : /// Represents image files stored on the file system.
     431              : ///
     432              : /// Stores image metadata and supports saving, moving, deleting,
     433              : /// and conversion to in-memory representation.
     434              : class ImageFileMedia extends FileMediaSource<ImageType> {
     435              :   /// Internal constructor for creating image file media.
     436              :   ///
     437              :   /// Parameters:
     438              :   /// - [file]: The image file
     439              :   /// - [name]: Display name
     440              :   /// - [size]: File size
     441              :   /// - [mimeType]: MIME type of the image
     442            1 :   ImageFileMedia._({
     443              :     required super.file,
     444              :     required super.name,
     445              :     required super.size,
     446              :     required super.mimeType,
     447            2 :   }) : super._(metadata: ImageType());
     448              : 
     449              :   /// Creates an [ImageFileMedia] from a file path.
     450              :   ///
     451              :   /// Parameters:
     452              :   /// - [path]: The file system path to the image
     453              :   /// - [name]: Optional custom display name
     454              :   /// - [mimeType]: Optional MIME type override
     455              :   /// - [size]: Optional pre-computed file size
     456            0 :   static Future<ImageFileMedia> fromPath(
     457              :     String path, {
     458              :     String? name,
     459              :     String? mimeType,
     460              :     FileSize? size,
     461              :   }) async {
     462            0 :     final file = XFile(
     463              :       path,
     464              :       name: name,
     465              :       mimeType: mimeType,
     466            0 :       length: size?.inBytes,
     467              :     );
     468            0 :     return fromFile(
     469              :       file,
     470              :       name: name,
     471              :       mimeType: mimeType,
     472              :       size: size,
     473              :     );
     474              :   }
     475              : 
     476              :   /// Creates an [ImageFileMedia] from an XFile object.
     477              :   ///
     478              :   /// Parameters:
     479              :   /// - [file]: The XFile representing the image
     480              :   /// - [name]: Optional custom display name
     481              :   /// - [mimeType]: Optional MIME type override
     482              :   /// - [size]: Optional pre-computed file size, auto-detected if not provided
     483            1 :   static Future<ImageFileMedia> fromFile(
     484              :     XFile file, {
     485              :     String? name,
     486              :     String? mimeType,
     487              :     FileSize? size,
     488              :   }) async {
     489            1 :     return ImageFileMedia._(
     490              :       file: file,
     491            0 :       size: size ?? await file.size(),
     492              :       name: name,
     493              :       mimeType: mimeType,
     494              :     );
     495              :   }
     496              : 
     497              :   /// Saves this image to the specified file path.
     498              :   ///
     499              :   /// Creates the directory if it doesn't exist, then saves the file
     500              :   /// and returns a new instance pointing to the saved location.
     501            1 :   @override
     502              :   Future<ImageFileMedia> saveTo(String path) async {
     503            2 :     await PlatformUtils.instance.createDirectoryIfNotExists(path);
     504            2 :     await file.saveTo(path);
     505            1 :     return ImageFileMedia._(
     506            1 :       file: XFile(
     507              :         path,
     508            1 :         name: super.name,
     509            1 :         mimeType: super.mimeType,
     510            2 :         length: size?.inBytes,
     511              :       ),
     512            1 :       size: size ?? await file.size(),
     513            1 :       name: name,
     514            1 :       mimeType: mimeType,
     515              :     );
     516              :   }
     517              : 
     518              :   /// Converts this image to an in-memory representation.
     519              :   ///
     520              :   /// Loads the entire file content into memory as a byte array.
     521              :   /// Useful for uploading or processing without file system access.
     522            1 :   @override
     523              :   Future<MemoryMediaSource<ImageType>> convertToMemory() async {
     524            1 :     return ImageMemoryMedia(
     525            2 :       await file.readAsBytes(),
     526            1 :       name: name,
     527            1 :       mimeType: mimeType,
     528              :     );
     529              :   }
     530              : }
     531              : 
     532              : /// Represents document files stored on the file system.
     533              : ///
     534              : /// Supports documents like PDF, DOC, XLSX, etc. Provides saving, moving,
     535              : /// deleting, and conversion to in-memory representation.
     536              : class DocumentFileMedia extends FileMediaSource<DocumentType> {
     537              :   /// Internal constructor for creating document file media.
     538              :   ///
     539              :   /// Parameters:
     540              :   /// - [file]: The document file
     541              :   /// - [name]: Display name
     542              :   /// - [size]: File size
     543              :   /// - [mimeType]: MIME type of the document
     544            1 :   DocumentFileMedia._({
     545              :     required super.file,
     546              :     required super.name,
     547              :     required super.size,
     548              :     required super.mimeType,
     549            2 :   }) : super._(metadata: DocumentType());
     550              : 
     551              :   /// Creates a [DocumentFileMedia] from a file path.
     552              :   ///
     553              :   /// Parameters:
     554              :   /// - [path]: The file system path to the document
     555              :   /// - [name]: Optional custom display name
     556              :   /// - [mimeType]: Optional MIME type override
     557              :   /// - [size]: Optional pre-computed file size
     558            0 :   static Future<DocumentFileMedia> fromPath(
     559              :     String path, {
     560              :     String? name,
     561              :     String? mimeType,
     562              :     FileSize? size,
     563              :   }) async {
     564            0 :     final file = XFile(
     565              :       path,
     566              :       name: name,
     567              :       mimeType: mimeType,
     568            0 :       length: size?.inBytes,
     569              :     );
     570            0 :     return fromFile(
     571              :       file,
     572              :       name: name,
     573              :       mimeType: mimeType,
     574              :       size: size,
     575              :     );
     576              :   }
     577              : 
     578              :   /// Creates a [DocumentFileMedia] from an XFile object.
     579              :   ///
     580              :   /// Parameters:
     581              :   /// - [file]: The XFile representing the document
     582              :   /// - [name]: Optional custom display name
     583              :   /// - [mimeType]: Optional MIME type override
     584              :   /// - [size]: Optional pre-computed file size, auto-detected if not provided
     585            1 :   static Future<DocumentFileMedia> fromFile(
     586              :     XFile file, {
     587              :     String? name,
     588              :     String? mimeType,
     589              :     FileSize? size,
     590              :   }) async {
     591            1 :     return DocumentFileMedia._(
     592              :       file: file,
     593            0 :       size: size ?? await file.size(),
     594              :       name: name,
     595              :       mimeType: mimeType,
     596              :     );
     597              :   }
     598              : 
     599              :   /// Saves this document to the specified file path.
     600              :   ///
     601              :   /// Creates the directory if it doesn't exist, then saves the file
     602              :   /// and returns a new instance pointing to the saved location.
     603            1 :   @override
     604              :   Future<DocumentFileMedia> saveTo(String path) async {
     605            2 :     await PlatformUtils.instance.createDirectoryIfNotExists(path);
     606            2 :     await file.saveTo(path);
     607            1 :     return DocumentFileMedia._(
     608            1 :       file: XFile(
     609              :         path,
     610            1 :         name: super.name,
     611            1 :         mimeType: super.mimeType,
     612            2 :         length: size?.inBytes,
     613              :       ),
     614            1 :       size: size ?? await file.size(),
     615            1 :       name: name,
     616            1 :       mimeType: mimeType,
     617              :     );
     618              :   }
     619              : 
     620              :   /// Converts this document to an in-memory representation.
     621              :   ///
     622              :   /// Loads the entire file content into memory as a byte array.
     623              :   /// Useful for uploading or processing without file system access.
     624            0 :   @override
     625              :   Future<MemoryMediaSource<DocumentType>> convertToMemory() async {
     626            0 :     return DocumentMemoryMedia(
     627            0 :       await file.readAsBytes(),
     628            0 :       name: name,
     629            0 :       mimeType: mimeType,
     630              :     );
     631              :   }
     632              : }
     633              : 
     634              : /// Represents files of unclassified or unknown types.
     635              : ///
     636              : /// Used for media files that don't fit into the standard categories
     637              : /// (video, audio, image, document). Provides the same operations as
     638              : /// other file media types.
     639              : class OtherTypeFileMedia extends FileMediaSource<OtherType> {
     640              :   /// Internal constructor for creating other type file media.
     641              :   ///
     642              :   /// Parameters:
     643              :   /// - [file]: The file
     644              :   /// - [name]: Display name
     645              :   /// - [size]: File size
     646              :   /// - [mimeType]: MIME type of the file
     647            1 :   @override
     648              :   OtherTypeFileMedia._({
     649              :     required super.file,
     650              :     required super.name,
     651              :     required super.size,
     652              :     required super.mimeType,
     653            2 :   }) : super._(metadata: OtherType());
     654              : 
     655              :   /// Creates an [OtherTypeFileMedia] from a file path.
     656              :   ///
     657              :   /// Parameters:
     658              :   /// - [path]: The file system path to the file
     659              :   /// - [name]: Optional custom display name
     660              :   /// - [mimeType]: Optional MIME type override
     661              :   /// - [size]: Optional pre-computed file size
     662            0 :   static Future<OtherTypeFileMedia> fromPath(
     663              :     String path, {
     664              :     String? name,
     665              :     String? mimeType,
     666              :     FileSize? size,
     667              :   }) {
     668            0 :     final file = XFile(
     669              :       path,
     670              :       name: name,
     671              :       mimeType: mimeType,
     672            0 :       length: size?.inBytes,
     673              :     );
     674            0 :     return fromFile(
     675              :       file,
     676              :       name: name,
     677              :       mimeType: mimeType,
     678              :       size: size,
     679              :     );
     680              :   }
     681              : 
     682              :   /// Creates an [OtherTypeFileMedia] from an XFile object.
     683              :   ///
     684              :   /// Parameters:
     685              :   /// - [file]: The XFile representing the file
     686              :   /// - [name]: Optional custom display name
     687              :   /// - [mimeType]: Optional MIME type override
     688              :   /// - [size]: Optional pre-computed file size, auto-detected if not provided
     689            1 :   static Future<OtherTypeFileMedia> fromFile(
     690              :     XFile file, {
     691              :     String? name,
     692              :     String? mimeType,
     693              :     FileSize? size,
     694              :   }) async {
     695            1 :     return OtherTypeFileMedia._(
     696              :       file: file,
     697            0 :       size: size ?? await file.size(),
     698              :       name: name,
     699              :       mimeType: mimeType,
     700              :     );
     701              :   }
     702              : 
     703              :   /// Saves this file to the specified file path.
     704              :   ///
     705              :   /// Creates the directory if it doesn't exist, then saves the file
     706              :   /// and returns a new instance pointing to the saved location.
     707            1 :   @override
     708              :   Future<OtherTypeFileMedia> saveTo(String path) async {
     709            2 :     await PlatformUtils.instance.createDirectoryIfNotExists(path);
     710            2 :     await file.saveTo(path);
     711            1 :     return OtherTypeFileMedia._(
     712            3 :       file: XFile(path, name: super.name, mimeType: super.mimeType),
     713            2 :       size: await file.size(),
     714            1 :       name: name,
     715            1 :       mimeType: mimeType,
     716              :     );
     717              :   }
     718              : 
     719              :   /// Converts this file to an in-memory representation.
     720              :   ///
     721              :   /// Loads the entire file content into memory as a byte array.
     722              :   /// Useful for uploading or processing without file system access.
     723            0 :   @override
     724              :   Future<MemoryMediaSource<OtherType>> convertToMemory() async {
     725            0 :     return OtherTypeMemoryMedia(
     726            0 :       await file.readAsBytes(),
     727            0 :       name: name,
     728            0 :       mimeType: mimeType,
     729              :     );
     730              :   }
     731              : }
        

Generated by: LCOV version 2.3.2-1