### Install Yantl Stable Version with sbt Source: https://github.com/arturaz/yantl/blob/main/docs/000_installation.md Add the Yantl stable library dependency to your `build.sbt` file. This is the standard way to include the library for use in your Scala project. ```scala libraryDependencies += "io.github.arturaz" %% "yantl" % "@VERSION@" ``` -------------------------------- ### Install Yantl Snapshot Version with sbt Source: https://github.com/arturaz/yantl/blob/main/docs/000_installation.md Add the Yantl snapshot library dependency to your `build.sbt` file, including the sonatype OSS repositories. This allows you to use the latest development version. ```scala resolvers ++= Resolver.sonatypeOssRepos("snapshots") libraryDependencies += "io.github.arturaz" %% "yantl" % "@SNAPSHOT_VERSION@" ``` -------------------------------- ### Install Yantl Snapshot Version with mill Source: https://github.com/arturaz/yantl/blob/main/docs/000_installation.md Add the Yantl snapshot library dependency to your `build.sc` file with mill, configuring the sonatype snapshots repository. This is for using the bleeding-edge version. ```scala override def repositoriesTask = T.task { super.repositoriesTask() ++ Seq( coursier.Repositories.sonatype("snapshots") ) } override def ivyDeps = Agg( ivy"io.github.arturaz::yantl:@SNAPSHOT_VERSION@" ) ``` -------------------------------- ### Install Yantl Stable Version with mill Source: https://github.com/arturaz/yantl/blob/main/docs/000_installation.md Add the Yantl stable library dependency to your `build.sc` file when using the mill build tool. This ensures the library is available for your project. ```scala override def ivyDeps = Agg( ivy"io.github.arturaz::yantl:@VERSION@" ) ``` -------------------------------- ### Validator Composition and Usage (Scala) Source: https://github.com/arturaz/yantl/blob/main/docs/002_validator_rules.md Illustrates how to combine multiple `ValidatorRule` objects into a single `Validator` using `Validator.of`. The example demonstrates creating a validator that checks for a minimum value, maximum value, and whether the number is even. It then shows how to use the `validate` method to check specific values. ```Scala import yantl.* val validator = Validator.of( ValidatorRule.minValue(0L), ValidatorRule.maxValue(100L), isEven ) validator.validate(50) validator.validate(51) validator.validate(101) ``` -------------------------------- ### Custom Validator Rule Creation (Scala) Source: https://github.com/arturaz/yantl/blob/main/docs/002_validator_rules.md Shows how to define a custom validator rule using `ValidatorRule.of`. This method accepts a function that returns an Option. If the function returns `Some`, the validation fails with the provided value; if it returns `None`, the validation passes. This example creates a rule to check if a number is even. ```Scala case class NotEven(value: Long) val isEven = ValidatorRule.of((v: Long) => if v % 2 == 0 then None else Some(NotEven(v))) ``` -------------------------------- ### Fractional Operations with StdLibGivens Source: https://github.com/arturaz/yantl/blob/main/docs/005_standard_given_instances.md Illustrates the Fractional type class instances from StdLibGivens for ScoreFloat newtypes, enabling the division operation for real numbers. ```scala val divisionFloat = scoreFloat1 / scoreFloat2 ``` -------------------------------- ### Numeric Operations with StdLibGivens Source: https://github.com/arturaz/yantl/blob/main/docs/005_standard_given_instances.md Demonstrates the use of Numeric type class instances provided by StdLibGivens for Score newtypes, enabling addition, subtraction, and multiplication. ```scala val addition = score1 + score2 val subtraction = score1 - score2 val multiplication = score1 * score2 ``` -------------------------------- ### Integral Operations with StdLibGivens Source: https://github.com/arturaz/yantl/blob/main/docs/005_standard_given_instances.md Showcases the Integral type class instances from StdLibGivens for Score newtypes, facilitating division and modulus operations for natural numbers. ```scala val division = score1 / score2 val modulus = score1 % score2 ``` -------------------------------- ### Create Validated 'Age' Newtype Instances Source: https://github.com/arturaz/yantl/blob/main/docs/001_defining_newtypes.md Demonstrates various ways to create instances of the validated 'Age' newtype. Includes safe creation, creation with string errors, and unsafe creation. It also shows how to convert errors to strings using an AsString instance. ```scala // Safe creation Age.make(25) Age.make(-5) // With errors as strings. // You need to define how to convert the error messages to strings first. given [A]: AsString[A] = AsString.fromToString // Creation with multiple string error messages Age.make.asStrings(-5) // Creation with a single string error message Age.make.asString(-5) // Performs no checking, allowing invalid values to be created Age.make.unsafe(-5) ``` -------------------------------- ### Compose and Use Chained Newtypes 'ChainedGoogleMailEmail' Source: https://github.com/arturaz/yantl/blob/main/docs/001_defining_newtypes.md Shows how to compose existing newtypes using `compose` to create a new, more specific type 'ChainedGoogleMailEmail'. It then demonstrates creating instances of this chained newtype and performing comparisons. ```scala val ChainedGoogleMailEmail = Email.compose(GoogleMailEmail) type ChainedGoogleMailEmail = ChainedGoogleMailEmail.Type val notAnEmail = ChainedGoogleMailEmail.make("foo") val outlook = ChainedGoogleMailEmail.make("foo@outlook.com") val gmail = ChainedGoogleMailEmail.make("foo@gmail.com") gmail == Email.make("foo@gmail.com").flatMap(GoogleMailEmail.make(_)) ``` -------------------------------- ### Create Unvalidated 'Name' Newtype Instance Source: https://github.com/arturaz/yantl/blob/main/docs/001_defining_newtypes.md Demonstrates the creation of an instance for the unvalidated 'Name' newtype. This is a straightforward wrapping of a String value. ```scala Name("John") ``` -------------------------------- ### Built-in Validator Rules (Scala) Source: https://github.com/arturaz/yantl/blob/main/docs/002_validator_rules.md Demonstrates the usage of predefined validator rules for minimum value, maximum value, range, minimum length, maximum length, non-empty, non-empty string, non-blank string, and whitespace constraints. These rules can be directly instantiated or used with custom length/emptiness checks. ```Scala import yantl.* val minValueValidator = ValidatorRule.minValue(0L) val maxValueValidator = ValidatorRule.maxValue(100L) val betweenValidator = ValidatorRule.between(0L, 100L) val minLengthOfVectorValidator = ValidatorRule.minLength(2, getLength = (_: Vector[String]).size) val maxLengthOfVectorValidator = ValidatorRule.maxLength(50, getLength = (_: Vector[String]).size) val minLengthValidator = ValidatorRule.minLength(2) val maxLengthValidator = ValidatorRule.maxLength(50) val nonEmptyValidator = ValidatorRule.nonEmpty(isEmpty = (_: Vector[String]).isEmpty) val nonEmptyStringValidator = ValidatorRule.nonEmptyString val nonBlankStringValidator = ValidatorRule.nonBlankString val withoutSurroundingWhitespaceValidator = ValidatorRule.withoutSurroundingWhitespace ``` -------------------------------- ### Provide Typeclass Instances for Validated Newtypes in Scala Source: https://github.com/arturaz/yantl/blob/main/docs/003_providing_typeclasses.md Provides generic `SerializeToString` and `DeserializeFromString` typeclass instances for validated newtypes. These instances leverage existing typeclass instances for the underlying type, automatically enabling serialization and deserialization for the newtypes. ```scala given newTypeSerializeToString[TUnderlying, TWrapper](using newType: yantl.Newtype.WithType[TUnderlying, TWrapper], serializer: SerializeToString[TUnderlying], ): SerializeToString[TWrapper] = t => serializer.serialize(t.unwrap) given newTypeDeserializeFromString[TUnderlying, TWrapper, TError](using newType: yantl.Newtype.WithTypeAndError[TUnderlying, TWrapper, TError], asString: yantl.AsString[TError], deserializer: DeserializeFromString[TUnderlying], ): DeserializeFromString[TWrapper] = str => deserializer.deserialize(str).flatMap(newType.make.asString) // You need to define how to convert the error messages to strings first. given [A]: AsString[A] = AsString.fromToString // The instances are automatically provided summon[SerializeToString[Age]] summon[DeserializeFromString[Age]] summon[SerializeToString[Name]] summon[DeserializeFromString[Name]] ``` -------------------------------- ### Yantl: Error as String Requirement (Scala) Source: https://github.com/arturaz/yantl/blob/main/docs/090_changelog.md Updates Yantl's `Make` functions that return errors as strings to now require an `AsString[TError]` instance. This change enforces a consistent way of handling string representations of errors, with a default `.toString()` implementation available via `AsString.fromToString`. ```scala AsString[TError] AsString.fromToString ``` -------------------------------- ### Define Newtypes with StdLibGivens Source: https://github.com/arturaz/yantl/blob/main/docs/005_standard_given_instances.md Defines newtype wrappers for Long and Float using yantl's Newtype.WithoutValidationOf and includes StdLibGivens trait for standard type class instances. Also imports extra implicits for math operations. ```scala import yantl.* object Score extends Newtype.WithoutValidationOf[Long] with StdLibGivens with math.Integral.ExtraImplicits type Score = Score.Type object ScoreFloat extends Newtype.WithoutValidationOf[Float] with StdLibGivens with math.Fractional.ExtraImplicits type ScoreFloat = ScoreFloat.Type val score1 = Score(50) val score2 = Score(100) val scoreFloat1 = ScoreFloat(50) val scoreFloat2 = ScoreFloat(100) ``` -------------------------------- ### Provide Typeclass Instances for Unvalidated Newtypes in Scala Source: https://github.com/arturaz/yantl/blob/main/docs/003_providing_typeclasses.md Provides a generic `DeserializeFromString` typeclass instance specifically for unvalidated newtypes. This instance uses the underlying type's deserializer and the newtype's apply method to create instances of the newtype. ```scala given newTypeDeserializeUnvalidatedFromString[TUnderlying, TWrapper](using newType: yantl.Newtype.WithUnvalidatedType[TUnderlying, TWrapper], deserializer: DeserializeFromString[TUnderlying], ): DeserializeFromString[TWrapper] = str => deserializer.deserialize(str).map(newType.apply) // The instance is automatically provided summon[DeserializeFromString[Name]] ``` -------------------------------- ### Best Practice: Define Object and Type Alias for Newtypes Source: https://github.com/arturaz/yantl/blob/main/docs/001_defining_newtypes.md Illustrates the best practice of defining both an object and a type alias for a newtype. The object provides the implementation and factory methods, while the type alias allows using the newtype name directly in type signatures. ```scala object MyType extends Newtype.WithoutValidationOf[String] type MyType = MyType.Type // Allows using `MyType` as your type in the codebase ``` -------------------------------- ### Create Validated 'Age' Newtype Instance with Exception Source: https://github.com/arturaz/yantl/blob/main/docs/001_defining_newtypes.md Shows how to create a validated 'Age' newtype instance using makeOrThrow, which throws an exception if the provided value is invalid. This is suitable for statically known valid values. ```scala Age.make.orThrow(-5) ``` -------------------------------- ### Yantl: Validate and Make Traits Introduction (Scala) Source: https://github.com/arturaz/yantl/blob/main/docs/090_changelog.md Introduces core `Validate` and `Make` traits in Yantl, defining the fundamental structures for validation and data transformation. This version also refactors `Newtype` to extend `Make`, along with changes to its associated methods like `makeUnsafe`, `makeAsString`, and `makeOrThrow`. ```scala Validate[-TInput, +TError] Make[-TInput, +TError, +TOutput] Newtype.object make extends Make[...] MyNewType.makeUnsafe -> MyNewType.make.unsafe MyNewType.makeAsString -> MyNewType.make.asString MyNewType.makeAsStrings -> MyNewType.make.asStrings MyNewType.makeOrThrow -> MyNewType.make.orThrow ``` -------------------------------- ### Define Chained Newtypes 'Email' and 'GoogleMailEmail' Source: https://github.com/arturaz/yantl/blob/main/docs/001_defining_newtypes.md Demonstrates defining chained newtypes. 'Email' is a validated newtype with a custom email format check. 'GoogleMailEmail' further refines 'Email' to specifically check for Gmail addresses. ```scala case class NotAnEmail(email: String) case object Email extends Newtype.ValidatedOf(Validator.of( ValidatorRule.of { (email: String) => if (email.contains("@")) None else Some(NotAnEmail(email)) } )) type Email = Email.Type case class NotAGoogleMail(email: Email) case object GoogleMailEmail extends Newtype.ValidatedOf(Validator.of( ValidatorRule.of { (email: Email) => if (Email.unwrap(email).endsWith("@gmail.com")) None else Some(NotAGoogleMail(email)) } )) ``` -------------------------------- ### Define Refined Newtype 'ForumTopicStrict' with Additional Rules Source: https://github.com/arturaz/yantl/blob/main/docs/001_defining_newtypes.md Defines a more specific newtype 'ForumTopicStrict' by extending 'NewtypeString' and composing validation rules from 'NewtypeNonEmptyString' with an additional minimum length requirement. ```scala case object ForumTopicStrict extends NewtypeString { type TError = ValidatorRule.HadSurroundingWhitespace | ValidatorRule.WasBlank | ValidatorRule.UnderMinLength[String] override val validate = NewtypeNonEmptyString.validator and Validator.of(ValidatorRule.minLength(10)) } type ForumTopicStrict = ForumTopicStrict.Type ForumTopicStrict.make("What are newtypes?") ForumTopicStrict.make("newtypes?") ``` -------------------------------- ### Define Serialization and Deserialization Typeclasses in Scala Source: https://github.com/arturaz/yantl/blob/main/docs/003_providing_typeclasses.md Defines `SerializeToString` and `DeserializeFromString` typeclasses for handling serialization and deserialization of types to and from strings. It includes default implementations for `String` and `Long`. ```scala trait SerializeToString[T] { def serialize(t: T): String } object SerializeToString { given SerializeToString[String] = str => str given SerializeToString[Long] = _.toString } trait DeserializeFromString[T] { def deserialize(s: String): Either[String, T] } object DeserializeFromString { given DeserializeFromString[String] = Right(_) given DeserializeFromString[Long] = str => str.toLongOption.toRight(s"Not a long: $str") } ``` -------------------------------- ### Define Specific Newtype 'ForumTopic' from Intermediary Source: https://github.com/arturaz/yantl/blob/main/docs/001_defining_newtypes.md Defines a concrete newtype 'ForumTopic' that extends the 'NewtypeNonEmptyString' trait, inheriting its validation rules and functionality. It demonstrates how to use intermediary newtypes for common patterns. ```scala case object ForumTopic extends NewtypeNonEmptyString type ForumTopic = ForumTopic.Type ForumTopic.make("What are newtypes?") ForumTopic.make("") ``` -------------------------------- ### Yantl: Map Input with Extra Validation (Scala) Source: https://github.com/arturaz/yantl/blob/main/docs/090_changelog.md Introduces `Make.mapInputWithExtraValidation` for enhanced input validation in Yantl. This method allows for more sophisticated data processing by chaining validation steps. It is part of the Yantl library, likely used for building complex data transformations. ```scala Make.mapInputWithExtraValidation ``` -------------------------------- ### Localize Age Validation Errors in Scala Source: https://github.com/arturaz/yantl/blob/main/docs/004_making_localized_error_messages.md Demonstrates how to localize error messages for invalid `Age` values. By setting the `LocaleEnum` to `En` and calling `.localized` on the validation errors, the raw error codes are converted into user-friendly messages, showing the result of applying the defined localization. ```scala given LocaleEnum = LocaleEnum.En Age.make(-1).left.map(errors => errors.map(_.localized)) Age.make(105).left.map(errors => errors.map(_.localized)) ``` -------------------------------- ### Define Newtypes in Scala using yantl Source: https://github.com/arturaz/yantl/blob/main/docs/003_providing_typeclasses.md Defines newtypes `Age` and `Name` using the `yantl` library. `Age` is a validated newtype with a minimum value constraint, while `Name` is an unvalidated newtype based on `String`. ```scala import yantl.* object Age extends Newtype.ValidatedOf(IArray(ValidatorRule.minValue(0L))) type Age = Age.Type object Name extends Newtype.WithoutValidationOf[String] type Name = Name.Type ``` -------------------------------- ### Yantl: Validate.of Functionality (Scala) Source: https://github.com/arturaz/yantl/blob/main/docs/090_changelog.md Adds the `Validate.of` function to the Yantl library. This function is likely used for creating validation instances, providing a more direct way to define validation rules. It's a utility for the validation subsystem. ```scala Validate.of ``` -------------------------------- ### Yantl: Newtype Validator Replacement (Scala) Source: https://github.com/arturaz/yantl/blob/main/docs/090_changelog.md This snippet details a breaking change in Yantl where `Newtype.validator` has been replaced by `Newtype.validate`. This suggests a refactoring or API improvement within the Newtype module. It also introduces `INewtype` and related composition/validation functions. ```scala Newtype.validator Newtype.validate INewtype Newtype.compose Validate.noOp Validator.ofLazy ``` -------------------------------- ### Define Localized Error Messages for Age Rules in Scala Source: https://github.com/arturaz/yantl/blob/main/docs/004_making_localized_error_messages.md Provides localized error messages in English for `ValidatorRule.SmallerThan[Long]` and `ValidatorRule.LargerThan[Long]`. These `given` instances implement the `LocalizedTextOfValue` trait, mapping specific validation errors to human-readable strings, including dynamic values from the error. ```scala given LocalizedTextOfValue[ValidatorRule.SmallerThan[Long]] = LocalizedTextOfValue.of { case (err, LocaleEnum.En) => s"Must be actually born." } given LocalizedTextOfValue[ValidatorRule.LargerThan[Long]] = LocalizedTextOfValue.of { case (err, LocaleEnum.En) => s"Sorry, too old. Must be under ${err.maximum}, was ${err.actual}." } ``` -------------------------------- ### Define Validated Newtype 'Age' with Min Value Validation Source: https://github.com/arturaz/yantl/blob/main/docs/001_defining_newtypes.md Defines a newtype 'Age' that wraps a Long and validates that the value is non-negative using yantl's Validator.of and ValidatorRule.minValue. It provides safe creation methods and handles errors. ```scala import yantl.* case object Age extends Newtype.ValidatedOf(Validator.of(ValidatorRule.minValue(0L))) type Age = Age.Type ``` -------------------------------- ### Define Intermediary Newtype 'NewtypeNonEmptyString' Source: https://github.com/arturaz/yantl/blob/main/docs/001_defining_newtypes.md Defines an intermediary newtype trait 'NewtypeNonEmptyString' that enforces non-blank strings and disallows surrounding whitespace. It inherits from 'NewtypeString' and utilizes a predefined validator. ```scala trait NewtypeString extends Newtype.Of[String] { given CanEqual[Type, Type] = CanEqual.derived given Ordering[Type] = Ordering.by(unwrap) } trait NewtypeNonEmptyString extends NewtypeString { type TError = ValidatorRule.HadSurroundingWhitespace | ValidatorRule.WasBlank override val validate = NewtypeNonEmptyString.validator } object NewtypeNonEmptyString { val validator = Validator.of( ValidatorRule.nonBlankString, ValidatorRule.withoutSurroundingWhitespace, ) } ``` -------------------------------- ### Define Unvalidated Newtype 'Name' Wrapping String Source: https://github.com/arturaz/yantl/blob/main/docs/001_defining_newtypes.md Defines a newtype 'Name' that wraps a String without any validation rules, providing only type safety. It uses yantl's Newtype.WithoutValidationOf. ```scala object Name extends Newtype.WithoutValidationOf[String] type Name = Name.Type ``` -------------------------------- ### Define Localization Trait in Scala Source: https://github.com/arturaz/yantl/blob/main/docs/004_making_localized_error_messages.md Defines the `LocalizedTextOfValue` trait and its companion object, which provides a mechanism to associate localized text with specific types. It includes a helper method `of` for creating instances and an `inline given` for automatic derivation using `UnionDerivation`. This trait is essential for associating user-readable strings with error types. ```scala import yantl.* import io.github.irevive.union.derivation.* enum LocaleEnum { case En } trait LocalizedTextOfValue[A] { def text(a: A): LocaleEnum ?=> String } object LocalizedTextOfValue { /** Creates a new instance. */ def of[A](localize: (A, LocaleEnum) => String): LocalizedTextOfValue[A] = new { override def text(value: A): LocaleEnum ?=> String = (locale: LocaleEnum) ?=> localize(value, locale) } inline given derivedUnion[A](using IsUnion[A]): LocalizedTextOfValue[A] = UnionDerivation.derive[LocalizedTextOfValue, A] } extension [A](a: A) { def localized(using loc: LocalizedTextOfValue[A], locale: LocaleEnum): String = loc.text(a) } ``` -------------------------------- ### Yantl: Newtype Apply Method (Scala) Source: https://github.com/arturaz/yantl/blob/main/docs/090_changelog.md Modifies the `Newtype.Withoutvalidation.apply` method in Yantl to be non-final. This change allows for greater flexibility in extending or overriding the apply method for Newtype types without validation, promoting more advanced usage patterns. ```scala Newtype.Withoutvalidation.apply ``` -------------------------------- ### Define Newtype for Age Validation in Scala Source: https://github.com/arturaz/yantl/blob/main/docs/004_making_localized_error_messages.md Defines a `Newtype` named `Age` that is validated using `Validator.of` with a `ValidatorRule.between` constraint, ensuring the age is between 0 and 100. This creates a type-safe representation for age values and enforces validation rules. ```scala object Age extends Newtype.ValidatedOf(Validator.of(ValidatorRule.between(0L, 100L))) type Age = Age.Type ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.