""" fsrs.review_log --------- This module defines the ReviewLog and Rating classes. Classes: ReviewLog: Represents the log entry of a Card that has been reviewed. Rating: Enum representing the four possible ratings when reviewing a card. """ from __future__ import annotations from dataclasses import dataclass from datetime import datetime from typing import TypedDict import json from typing_extensions import Self from fsrs.rating import Rating class ReviewLogDict(TypedDict): """ JSON-serializable dictionary representation of a ReviewLog object. """ card_id: int rating: int review_datetime: str review_duration: int | None @dataclass class ReviewLog: """ Represents the log entry of a Card object that has been reviewed. Attributes: card_id: The id of the card being reviewed. rating: The rating given to the card during the review. review_datetime: The date and time of the review. review_duration: The number of milliseconds it took to review the card or None if unspecified. """ card_id: int rating: Rating review_datetime: datetime review_duration: int | None def to_dict( self, ) -> ReviewLogDict: """ Returns a dictionary representation of the ReviewLog object. Returns: ReviewLogDict: A dictionary representation of the ReviewLog object. """ return { "card_id": self.card_id, "rating": int(self.rating), "review_datetime": self.review_datetime.isoformat(), "review_duration": self.review_duration, } @classmethod def from_dict( cls, source_dict: ReviewLogDict, ) -> Self: """ Creates a ReviewLog object from an existing dictionary. Args: source_dict: A dictionary representing an existing ReviewLog object. Returns: Self: A ReviewLog object created from the provided dictionary. """ return cls( card_id=source_dict["card_id"], rating=Rating(int(source_dict["rating"])), review_datetime=datetime.fromisoformat(source_dict["review_datetime"]), review_duration=source_dict["review_duration"], ) def to_json(self, indent: int | str | None = None) -> str: """ Returns a JSON-serialized string of the ReviewLog object. Args: indent: Equivalent argument to the indent in json.dumps() Returns: str: A JSON-serialized string of the ReviewLog object. """ return json.dumps(self.to_dict(), indent=indent) @classmethod def from_json(cls, source_json: str) -> Self: """ Creates a ReviewLog object from a JSON-serialized string. Args: source_json: A JSON-serialized string of an existing ReviewLog object. Returns: Self: A ReviewLog object created from the JSON string. """ source_dict: ReviewLogDict = json.loads(source_json) return cls.from_dict(source_dict=source_dict) __all__ = ["ReviewLog"]