@@ -365,3 +365,303 @@ public struct PercentageColumnType: ColumnOutputTypeProtocol {
365365 PercentageColumnType ( PercentageColumnConfig ( value: config. value ?? value, precision: config. precision) )
366366 }
367367}
368+
369+ extension ColumnOutputTypeProtocol where Self == TextColumnType {
370+ /// Creates a TextColumnType from a non-optional String value.
371+ ///
372+ /// This convenience factory method provides a cleaner syntax for creating
373+ /// text column types in custom mappings.
374+ ///
375+ /// Example usage:
376+ /// ```swift
377+ /// Column(name: "Status", keyPath: \.status) { status in
378+ /// .string(status.rawValue.uppercased())
379+ /// }
380+ /// ```
381+ ///
382+ /// - Parameter text: The non-optional String value to display in the cell
383+ /// - Returns: A configured TextColumnType instance
384+ public static func string( _ text: String ) -> TextColumnType {
385+ . init( TextColumnConfig ( value: text) )
386+ }
387+ }
388+
389+ extension ColumnOutputTypeProtocol where Self == DateColumnType {
390+ /// Creates a DateColumnType from a non-optional Date value with timezone configuration.
391+ ///
392+ /// This convenience factory method simplifies date column creation in custom mappings
393+ /// while providing timezone control for accurate date representation.
394+ ///
395+ /// Example usage:
396+ /// ```swift
397+ /// Column(name: "Last Modified", keyPath: \.timestamp) { timestamp in
398+ /// .date(timestamp, timeZone: .utc)
399+ /// }
400+ /// ```
401+ ///
402+ /// - Parameters:
403+ /// - date: The non-optional Date value to display
404+ /// - timeZone: The timezone for date interpretation (default: current system timezone)
405+ /// - Returns: A configured DateColumnType instance
406+ public static func date( _ date: Date , timeZone: TimeZone = . current) -> DateColumnType {
407+ . init( DateColumnConfig ( value: date, timeZone: timeZone) )
408+ }
409+ }
410+
411+ extension ColumnOutputTypeProtocol where Self == BoolColumnType {
412+ /// Creates a BoolColumnType from a non-optional Bool value.
413+ ///
414+ /// This convenience factory method provides a cleaner syntax for creating
415+ /// boolean column types in custom mappings. Uses default boolean expressions
416+ /// and case strategy settings.
417+ ///
418+ /// Example usage:
419+ /// ```swift
420+ /// Column(name: "Is Premium", keyPath: \.subscriptionLevel) { level in
421+ /// .bool(level == .premium)
422+ /// }
423+ /// ```
424+ ///
425+ /// - Parameter value: The non-optional Bool value to display
426+ /// - Returns: A configured BoolColumnType instance with default formatting
427+ public static func bool( _ value: Bool ) -> BoolColumnType {
428+ . init( BoolColumnConfig ( value: value) )
429+ }
430+ }
431+
432+ extension ColumnOutputTypeProtocol where Self == URLColumnType {
433+ /// Creates a URLColumnType from a non-optional URL value.
434+ ///
435+ /// This convenience factory method provides a cleaner syntax for creating
436+ /// URL column types in custom mappings. URLs are displayed as their absolute
437+ /// string representation.
438+ ///
439+ /// Example usage:
440+ /// ```swift
441+ /// Column(name: "Documentation", keyPath: \.productId) { id in
442+ /// .url(URL(string: "https://docs.example.com/\(id)")!)
443+ /// }
444+ /// ```
445+ ///
446+ /// - Parameter url: The non-optional URL value to display
447+ /// - Returns: A configured URLColumnType instance
448+ public static func url( _ url: URL ) -> URLColumnType {
449+ . init( URLColumnConfig ( value: url) )
450+ }
451+ }
452+
453+ extension ColumnOutputTypeProtocol where Self == DoubleColumnType {
454+ /// Creates a DoubleColumnType from a non-optional Double value.
455+ ///
456+ /// This convenience factory method provides a cleaner syntax for creating
457+ /// numeric column types in custom mappings with floating-point values.
458+ ///
459+ /// Example usage:
460+ /// ```swift
461+ /// Column(name: "Calculated Price", keyPath: \.basePrice) { price in
462+ /// .double(price * 1.2) // Add 20% markup
463+ /// }
464+ /// ```
465+ ///
466+ /// - Parameter value: The non-optional Double value to display
467+ /// - Returns: A configured DoubleColumnType instance
468+ public static func double( _ value: Double ) -> DoubleColumnType {
469+ . init( DoubleColumnConfig ( value: value) )
470+ }
471+ }
472+
473+ extension ColumnOutputTypeProtocol where Self == IntColumnType {
474+ /// Creates an IntColumnType from a non-optional Int value.
475+ ///
476+ /// This convenience factory method provides a cleaner syntax for creating
477+ /// integer column types in custom mappings.
478+ ///
479+ /// Example usage:
480+ /// ```swift
481+ /// Column(name: "Days Until Due", keyPath: \.dueDate) { date in
482+ /// .int(Calendar.current.dateComponents([.day], from: Date(), to: date).day ?? 0)
483+ /// }
484+ /// ```
485+ ///
486+ /// - Parameter value: The non-optional Int value to display
487+ /// - Returns: A configured IntColumnType instance
488+ public static func int( _ value: Int ) -> IntColumnType {
489+ . init( IntColumnConfig ( value: value) )
490+ }
491+ }
492+
493+ extension ColumnOutputTypeProtocol where Self == PercentageColumnType {
494+ /// Creates a PercentageColumnType from a non-optional Double value with precision control.
495+ ///
496+ /// This convenience factory method provides a cleaner syntax for creating
497+ /// percentage column types in custom mappings. Values should be provided as
498+ /// decimals (0.5 = 50%).
499+ ///
500+ /// Example usage:
501+ /// ```swift
502+ /// Column(name: "Completion", keyPath: \.completed) { completed in
503+ /// .percentage(completed / total, precision: 1) // Shows as "50.0%"
504+ /// }
505+ /// ```
506+ ///
507+ /// - Parameters:
508+ /// - value: The non-optional percentage value as decimal (0.5 = 50%)
509+ /// - precision: Number of decimal places to display (default: 2)
510+ /// - Returns: A configured PercentageColumnType instance
511+ public static func percentage( _ value: Double , precision: Int = 2 ) -> PercentageColumnType {
512+ . init( PercentageColumnConfig ( value: value, precision: precision) )
513+ }
514+ }
515+
516+ // MARK: - Optional Support
517+
518+ extension ColumnOutputTypeProtocol where Self == TextColumnType {
519+ /// Creates a TextColumnType from an optional String value.
520+ ///
521+ /// This convenience factory method handles optional String values in custom mappings.
522+ /// Nil values are preserved and can be handled by Column's nilHandling mechanism.
523+ ///
524+ /// Example usage:
525+ /// ```swift
526+ /// Column(name: "Notes", keyPath: \.metadata) { metadata in
527+ /// .string(metadata["notes"]) // Returns String?
528+ /// }
529+ /// .defaultValue("No notes")
530+ /// ```
531+ ///
532+ /// - Parameter text: The optional String value to display
533+ /// - Returns: A configured TextColumnType instance that preserves nil
534+ public static func string( _ text: String ? ) -> TextColumnType {
535+ . init( TextColumnConfig ( value: text) )
536+ }
537+ }
538+
539+ extension ColumnOutputTypeProtocol where Self == DoubleColumnType {
540+ /// Creates a DoubleColumnType from an optional Double value.
541+ ///
542+ /// This convenience factory method handles optional numeric values in custom mappings.
543+ /// Nil values are preserved and can be handled by Column's nilHandling mechanism.
544+ ///
545+ /// Example usage:
546+ /// ```swift
547+ /// Column(name: "Discount", keyPath: \.couponCode) { code in
548+ /// .double(discountMap[code]) // Returns Double?
549+ /// }
550+ /// .defaultValue(0.0)
551+ /// ```
552+ ///
553+ /// - Parameter value: The optional Double value to display
554+ /// - Returns: A configured DoubleColumnType instance that preserves nil
555+ public static func double( _ value: Double ? ) -> DoubleColumnType {
556+ . init( DoubleColumnConfig ( value: value) )
557+ }
558+ }
559+
560+ extension ColumnOutputTypeProtocol where Self == IntColumnType {
561+ /// Creates an IntColumnType from an optional Int value.
562+ ///
563+ /// This convenience factory method handles optional integer values in custom mappings.
564+ /// Nil values are preserved and can be handled by Column's nilHandling mechanism.
565+ ///
566+ /// Example usage:
567+ /// ```swift
568+ /// Column(name: "Priority", keyPath: \.tags) { tags in
569+ /// .int(tags.first { $0.type == .priority }?.value) // Returns Int?
570+ /// }
571+ /// .defaultValue(0)
572+ /// ```
573+ ///
574+ /// - Parameter value: The optional Int value to display
575+ /// - Returns: A configured IntColumnType instance that preserves nil
576+ public static func int( _ value: Int ? ) -> IntColumnType {
577+ . init( IntColumnConfig ( value: value) )
578+ }
579+ }
580+
581+ extension ColumnOutputTypeProtocol where Self == DateColumnType {
582+ /// Creates a DateColumnType from an optional Date value with timezone configuration.
583+ ///
584+ /// This convenience factory method handles optional date values in custom mappings.
585+ /// Nil values are preserved and can be handled by Column's nilHandling mechanism.
586+ ///
587+ /// Example usage:
588+ /// ```swift
589+ /// Column(name: "Completed At", keyPath: \.status) { status in
590+ /// .date(status.isCompleted ? status.completionDate : nil, timeZone: .utc)
591+ /// }
592+ /// .defaultValue(Date())
593+ /// ```
594+ ///
595+ /// - Parameters:
596+ /// - date: The optional Date value to display
597+ /// - timeZone: The timezone for date interpretation (default: current system timezone)
598+ /// - Returns: A configured DateColumnType instance that preserves nil
599+ public static func date( _ date: Date ? , timeZone: TimeZone = . current) -> DateColumnType {
600+ . init( DateColumnConfig ( value: date, timeZone: timeZone) )
601+ }
602+ }
603+
604+ extension ColumnOutputTypeProtocol where Self == BoolColumnType {
605+ /// Creates a BoolColumnType from an optional Bool value.
606+ ///
607+ /// This convenience factory method handles optional boolean values in custom mappings.
608+ /// Nil values are preserved and can be handled by Column's nilHandling mechanism.
609+ ///
610+ /// Example usage:
611+ /// ```swift
612+ /// Column(name: "Verified", keyPath: \.profile) { profile in
613+ /// .bool(profile?.isVerified) // Returns Bool?
614+ /// }
615+ /// .defaultValue(false)
616+ /// ```
617+ ///
618+ /// - Parameter value: The optional Bool value to display
619+ /// - Returns: A configured BoolColumnType instance that preserves nil
620+ public static func bool( _ value: Bool ? ) -> BoolColumnType {
621+ . init( BoolColumnConfig ( value: value) )
622+ }
623+ }
624+
625+ extension ColumnOutputTypeProtocol where Self == URLColumnType {
626+ /// Creates a URLColumnType from an optional URL value.
627+ ///
628+ /// This convenience factory method handles optional URL values in custom mappings.
629+ /// Nil values are preserved and can be handled by Column's nilHandling mechanism.
630+ ///
631+ /// Example usage:
632+ /// ```swift
633+ /// Column(name: "Profile Link", keyPath: \.username) { username in
634+ /// .url(URL(string: "https://example.com/\(username)")) // Might fail
635+ /// }
636+ /// .defaultValue(URL(string: "https://example.com")!)
637+ /// ```
638+ ///
639+ /// - Parameter url: The optional URL value to display
640+ /// - Returns: A configured URLColumnType instance that preserves nil
641+ public static func url( _ url: URL ? ) -> URLColumnType {
642+ . init( URLColumnConfig ( value: url) )
643+ }
644+ }
645+
646+ extension ColumnOutputTypeProtocol where Self == PercentageColumnType {
647+ /// Creates a PercentageColumnType from an optional Double value with precision control.
648+ ///
649+ /// This convenience factory method handles optional percentage values in custom mappings.
650+ /// Nil values are preserved and can be handled by Column's nilHandling mechanism.
651+ ///
652+ /// Example usage:
653+ /// ```swift
654+ /// Column(name: "Success Rate", keyPath: \.metrics) { metrics in
655+ /// .percentage(metrics?.successRate, precision: 1) // Returns Double?
656+ /// }
657+ /// .defaultValue(0.0) // Shows as "0.0%"
658+ /// ```
659+ ///
660+ /// - Parameters:
661+ /// - value: The optional percentage value as decimal (0.5 = 50%)
662+ /// - precision: Number of decimal places to display (default: 2)
663+ /// - Returns: A configured PercentageColumnType instance that preserves nil
664+ public static func percentage( _ value: Double ? , precision: Int = 2 ) -> PercentageColumnType {
665+ . init( PercentageColumnConfig ( value: value, precision: precision) )
666+ }
667+ }
0 commit comments