import 'package:platform_macroable/platform_macroable.dart'; import 'carbon.dart'; /// A factory for creating Carbon instances with customizable behavior. /// /// Similar to Laravel's DateFactory, this provides a way to customize /// how Carbon instances are created and manipulated. class DateFactory { /// The default class that will be used for all created dates. static Type get defaultClassName => Carbon; /// The type (class) of dates that should be created. static Type? _dateClass; /// This callable may be used to intercept date creation. static Function? _callable; /// The Carbon factory that should be used when creating dates. static CarbonFactory? _factory; /// Use the given handler when generating dates. /// /// The handler can be: /// - A Type (class) that extends or implements Carbon /// - A Function that takes a Carbon and returns a Carbon /// - A CarbonFactory instance /// /// Example: /// ```dart /// // Using a custom class /// DateFactory.use(CustomCarbon); /// /// // Using a callable /// DateFactory.use((carbon) => carbon.addDays(1)); /// /// // Using a factory /// DateFactory.use(CustomCarbonFactory()); /// ``` static void use(dynamic handler) { if (handler is Function) { useCallable(handler); } else if (handler is Type) { useClass(handler); } else if (handler is CarbonFactory) { useFactory(handler); } else { throw ArgumentError( 'Invalid date creation handler. Please provide a Type, Function, or CarbonFactory.', ); } } /// Use the default date class when generating dates. /// /// Example: /// ```dart /// DateFactory.useDefault(); /// ``` static void useDefault() { _dateClass = null; _callable = null; _factory = null; } /// Execute the given callable on each date creation. /// /// Example: /// ```dart /// DateFactory.useCallable((carbon) => carbon.addDays(1)); /// ``` static void useCallable(Function callable) { _callable = callable; _dateClass = null; _factory = null; } /// Use the given date type (class) when generating dates. /// /// Example: /// ```dart /// DateFactory.useClass(CustomCarbon); /// ``` static void useClass(Type dateClass) { _dateClass = dateClass; _factory = null; _callable = null; } /// Use the given Carbon factory when generating dates. /// /// Example: /// ```dart /// DateFactory.useFactory(CustomCarbonFactory()); /// ``` static void useFactory(CarbonFactory factory) { _factory = factory; _dateClass = null; _callable = null; } /// Creates a new Carbon instance. /// /// Example: /// ```dart /// final date = DateFactory.create(2023, 1, 1); /// ``` static Carbon create([ int year = 0, int month = 1, int day = 1, int hour = 0, int minute = 0, int second = 0, String? tz, ]) { final carbon = Carbon(year, month, day, hour, minute, second); return _processDate(carbon); } /// Creates a Carbon instance from a DateTime. /// /// Example: /// ```dart /// final date = DateFactory.fromDateTime(DateTime.now()); /// ``` static Carbon fromDateTime(DateTime dateTime) { final carbon = Carbon.fromDateTime(dateTime); return _processDate(carbon); } /// Creates a Carbon instance for the current date and time. /// /// Example: /// ```dart /// final now = DateFactory.now(); /// ``` static Carbon now() { final carbon = Carbon.now(); return _processDate(carbon); } /// Creates a Carbon instance from milliseconds since epoch. /// /// Example: /// ```dart /// final date = DateFactory.fromMillisecondsSinceEpoch(1640995200000); /// ``` static Carbon fromMillisecondsSinceEpoch(int milliseconds, {bool isUtc = false}) { final carbon = Carbon.fromMillisecondsSinceEpoch(milliseconds, isUtc: isUtc); return _processDate(carbon); } /// Creates a Carbon instance from microseconds since epoch. /// /// Example: /// ```dart /// final date = DateFactory.fromMicrosecondsSinceEpoch(1640995200000000); /// ``` static Carbon fromMicrosecondsSinceEpoch(int microseconds, {bool isUtc = false}) { final carbon = Carbon.fromMicrosecondsSinceEpoch(microseconds, isUtc: isUtc); return _processDate(carbon); } /// Creates a Carbon instance from an ISO 8601 string. /// /// Example: /// ```dart /// final date = DateFactory.parse('2023-01-01T00:00:00Z'); /// ``` static Carbon parse(String input) { final carbon = Carbon.parse(input); return _processDate(carbon); } /// Creates a Carbon instance from a UUID's timestamp. /// /// Example: /// ```dart /// final date = DateFactory.fromUuid('71513cb4-f071-11ed-a0cf-325096b39f47'); /// ``` static Carbon fromUuid(String uuid) { final carbon = Carbon.fromUuid(uuid); return _processDate(carbon); } /// Process a Carbon instance through the configured handler. static Carbon _processDate(Carbon carbon) { if (_callable != null) { return _callable!(carbon); } if (_factory != null) { return _factory!.createFromCarbon(carbon); } if (_dateClass != null && _dateClass != Carbon) { throw UnimplementedError( 'Custom date classes not yet supported. Use a callable or factory instead.', ); } return carbon; } } /// Interface for creating Carbon instances. /// /// Implement this interface to provide custom Carbon creation logic. abstract class CarbonFactory { /// Creates a Carbon instance from another Carbon instance. Carbon createFromCarbon(Carbon carbon); }