Skip to content

Commit

Permalink
Eliminate badly-named type parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
propensive committed Jan 4, 2024
1 parent b370e4f commit 64cf4af
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 32 deletions.
2 changes: 1 addition & 1 deletion src/core/xmlparser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ object XmlInterpolation:
given Substitution[XmlInput, Text, "t"] with
def embed(value: Text) = XmlInput.Flat(value)

given genInsert[T](using writer: XmlEncoder[T]): Insertion[XmlInput, T] = value =>
given genInsert[ValueType](using writer: XmlEncoder[ValueType]): Insertion[XmlInput, ValueType] = value =>
XmlInput.Structured(writer.write(value))

object XmlInterpolator extends Interpolator[XmlInput, ParseState, XmlDoc]:
Expand Down
4 changes: 2 additions & 2 deletions src/core/xmlprinter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import anticipation.*
import spectacular.*
import gossamer.*

trait XmlPrinter[T]:
def print(doc: Xml): T
trait XmlPrinter[OutputType]:
def print(doc: Xml): OutputType

object XmlPrinter:
given XmlPrinter[Text] = StandardXmlPrinter(false)
Expand Down
14 changes: 7 additions & 7 deletions src/core/xmlreader.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,18 @@ import anticipation.*
import gossamer.*
import spectacular.*

trait XmlDecoder[T]:
def read(xml: Seq[Ast]): Option[T]
def map[S](fn: T => Option[S]): XmlDecoder[S] = read(_).flatMap(fn(_))
trait XmlDecoder[ValueType]:
def read(xml: Seq[Ast]): Option[ValueType]
def map[ValueType2](fn: ValueType => Option[ValueType2]): XmlDecoder[ValueType2] = read(_).flatMap(fn(_))

object XmlDecoder extends Derivation[XmlDecoder]:
given txt: XmlDecoder[Text] =
childElements(_).collect { case Ast.Textual(txt) => txt }.headOption

given [T](using decoder: Decoder[T]): XmlDecoder[T] = value => (value: @unchecked) match
case Ast.Element(_, Ast.Textual(text) +: _, _, _) +: _ => Some(text.decodeAs[T])
given [ValueType](using decoder: Decoder[ValueType]): XmlDecoder[ValueType] = value => (value: @unchecked) match
case Ast.Element(_, Ast.Textual(text) +: _, _, _) +: _ => Some(text.decodeAs[ValueType])

def join[T](caseClass: CaseClass[XmlDecoder, T]): XmlDecoder[T] = seq =>
def join[DerivationType](caseClass: CaseClass[XmlDecoder, DerivationType]): XmlDecoder[DerivationType] = seq =>
val elems = childElements(seq)

Some:
Expand All @@ -43,7 +43,7 @@ object XmlDecoder extends Derivation[XmlDecoder]:
.find(_.name.name.s == param.label)
.flatMap { e => param.typeclass.read(Seq(e)) }.get

def split[T](sealedTrait: SealedTrait[XmlDecoder, T]): XmlDecoder[T] = seq =>
def split[DerivationType](sealedTrait: SealedTrait[XmlDecoder, DerivationType]): XmlDecoder[DerivationType] = seq =>
seq.headOption match
case Some(Ast.Element(_, children, attributes, _)) =>
attributes
Expand Down
40 changes: 19 additions & 21 deletions src/core/xmlwriter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,19 @@ import spectacular.*
import gossamer.*

object XmlEncoder extends Derivation[XmlEncoder]:
given XmlEncoder[Text] = str => Ast.Element(XmlName(t"Text"), List(Ast.Textual(str)))
given XmlEncoder[String] = str => Ast.Element(XmlName(t"String"), List(Ast.Textual(str.show)))
given XmlEncoder[Text] = text => Ast.Element(XmlName(t"Text"), List(Ast.Textual(text)))
given XmlEncoder[String] = string => Ast.Element(XmlName(t"String"), List(Ast.Textual(string.tt)))

// given [T](using canon: Canonical[T]): XmlEncoder[T] = value =>
// Ast.Element(XmlName(t"value"), List(Ast.Textual(canon.serialize(value))))

given [T: XmlEncoder, Coll[E] <: Seq[E]]: XmlEncoder[Coll[T]] = xs =>
Ast.Element(XmlName(t"Seq"), xs.map(summon[XmlEncoder[T]].write(_)))
given [ValueType: XmlEncoder, CollectionType[ElementType] <: Seq[ElementType]]
: XmlEncoder[CollectionType[ValueType]] =
elements => Ast.Element(XmlName(t"Seq"), elements.map(summon[XmlEncoder[ValueType]].write(_)))

given XmlEncoder[Int] = int =>
Ast.Element(XmlName(t"Int"), List(Ast.Textual(int.show)))

private val attributeAttribute = xmlAttribute()

def join[T](caseClass: CaseClass[XmlEncoder, T]): XmlEncoder[T] = value =>
def join[DerivationType](caseClass: CaseClass[XmlEncoder, DerivationType]): XmlEncoder[DerivationType] = value =>
val elements = caseClass.params
.filter(!_.annotations.contains(attributeAttribute))
.map { p => p.typeclass.write(p.deref(value)).copy(name = XmlName(Text(p.label))) }
Expand All @@ -53,21 +51,21 @@ object XmlEncoder extends Derivation[XmlEncoder]:

Ast.Element(XmlName(tag), elements, attributes)

def split[T](sealedTrait: SealedTrait[XmlEncoder, T]): XmlEncoder[T] = value =>
sealedTrait.choose(value) { subtype =>
val xml = subtype.typeclass.write(subtype.cast(value))
Ast.Element(
XmlName(Text(sealedTrait.typeInfo.short)),
xml.children,
xml.attributes.updated(XmlName(t"type"), xml.name.name),
xml.namespaces
)
}
def split[DerivationType](sealedTrait: SealedTrait[XmlEncoder, DerivationType]): XmlEncoder[DerivationType] =
value =>
sealedTrait.choose(value): subtype =>
val xml = subtype.typeclass.write(subtype.cast(value))
Ast.Element(
XmlName(Text(sealedTrait.typeInfo.short)),
xml.children,
xml.attributes.updated(XmlName(t"type"), xml.name.name),
xml.namespaces
)

private def textElements(value: Ast.Element): Text =
value.children.collect { case Ast.Textual(txt) => txt }.join

trait XmlEncoder[-T]:
def write(value: T): Ast.Element
def contramap[S](fn: S => T): XmlEncoder[S] = value => write(fn(value))
trait XmlEncoder[-ValueType]:
def write(value: ValueType): Ast.Element
def contramap[ValueType2](fn: ValueType2 => ValueType): XmlEncoder[ValueType2] = value => write(fn(value))

6 changes: 5 additions & 1 deletion src/core/xylophone.scala
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,11 @@ extends Xml, Dynamic:
infix def +(other: Xml): XmlDoc raises XmlAccessError =
XmlDoc(Ast.Root(Xml.normalize(this) ++ Xml.normalize(other)*))

def as[T](using decoder: XmlDecoder[T]): T raises XmlAccessError | XmlReadError = apply().as[T]
def as
[ValueType]
(using decoder: XmlDecoder[ValueType])
: ValueType raises XmlAccessError raises XmlReadError =
apply().as[ValueType]

case class XmlNode(head: Int, path: XmlPath, root: Ast.Root) extends Xml, Dynamic:
def selectDynamic(tagName: String): Fragment = Fragment(Text(tagName), head :: path, root)
Expand Down

0 comments on commit 64cf4af

Please sign in to comment.