glp-companion/lib/features/meal_planner/domain/entities/macro_profile.dart

64 lines
1.8 KiB
Dart

/// Nutritional macros for a single recipe serving.
///
/// Pure Dart (no framework imports) so the value can travel from the
/// schema.org scraper through the drift-backed repository into the
/// presentation layer without leaking infrastructure concerns into the
/// domain.
class MacroProfile {
const MacroProfile({
this.calories = 0,
this.proteinGrams = 0,
this.carbsGrams = 0,
this.fatGrams = 0,
});
/// Energy content in kilocalories per serving.
final int calories;
/// Protein in grams; the primary lean-mass tracking metric for GLP-1
/// therapy (muscle-preservation target).
final double proteinGrams;
/// Carbohydrate content in grams per serving.
final double carbsGrams;
/// Fat content in grams per serving.
final double fatGrams;
/// `true` when no macro could be extracted (e.g. OpenGraph-only imports).
bool get isEmpty =>
calories == 0 &&
proteinGrams == 0 &&
carbsGrams == 0 &&
fatGrams == 0;
MacroProfile copyWith({
int? calories,
double? proteinGrams,
double? carbsGrams,
double? fatGrams,
}) =>
MacroProfile(
calories: calories ?? this.calories,
proteinGrams: proteinGrams ?? this.proteinGrams,
carbsGrams: carbsGrams ?? this.carbsGrams,
fatGrams: fatGrams ?? this.fatGrams,
);
@override
bool operator ==(Object other) =>
other is MacroProfile &&
other.calories == calories &&
other.proteinGrams == proteinGrams &&
other.carbsGrams == carbsGrams &&
other.fatGrams == fatGrams;
@override
int get hashCode => Object.hash(calories, proteinGrams, carbsGrams, fatGrams);
@override
String toString() =>
'MacroProfile($calories kcal, P $proteinGrams g, '
'C $carbsGrams g, F $fatGrams g)';
}