Serializing Templated Container Types - spray

I've been struggling with this for a few hours. I'm hoping someone could assist me in understanding where the problem is.
Spray-JSON has a test case here
https://github.com/spray/spray-json/blob/master/src/test/scala/spray/json/AdditionalFormatsSpec.scala
case class Container[A](inner: Option[A])
object ReaderProtocol extends DefaultJsonProtocol {
implicit def containerReader[T :JsonFormat] =
new JsonReader[Container[T]] {
def read(value: JsValue) = value match {
case JsObject(fields) if fields.contains("content") =>
Container(Some(jsonReader[T].read(fields("content"))))
case _ => deserializationError("Unexpected format: " + value.toString)
}
}
}
}
that shows how you can serialize a container type. I've attempted to adapt this to my situaiton.
case class ListResponseObject[A](url : String, data : Seq[A])
object ListResponseWriterProtocol extends DefaultJsonProtocol {
implicit def containerWriter[T: JsonFormat] = lift {
new JsonWriter[ListResponseObject[T]] {
def write(obj: ListResponseObject[T]) = JsObject(
"object" -> JsString("object"),
"url" -> JsString(obj.url),
"count" -> JsNumber(obj.data.length),
"data" -> obj.data.toJson
)
}
}
}
Unfortunately, when I attempt to use this here
{ ctx : RequestContext =>
ask(cardTokenActor, ListMessage(account))
.mapTo[ListResponse]
.onComplete {
case Success(ListResponse(list: ListResponseObject[CardToken])) =>
ctx.complete(list)
case Success(_) => ctx.complete(NotFound)
case Failure(e: Throwable ) => logAndFail(ctx, e)
}
}
I run into this error
161: could not find implicit value for evidence parameter of type
spray.httpx.marshalling.Marshaller[com.smoothpay.services.ListResponseObject
[com.smoothpay.services.cardtoken.entity.CardToken]]
[error] case Success(ListResponse(list: ListResponseObject[CardToken])) =>
ctx.complete(list)
I've also got all the right imports in place.
import spray.httpx.SprayJsonSupport._
import spray.httpx.marshalling._
import spray.http._
import spray.json._
I'm curious where the problem could be. Appreciate the help in advance.

You can make it a bit easier, i think that should help:
case class ListResponseObject[A](url : String, data : Seq[A])
object ListResponseWriterProtocol extends DefaultJsonProtocol {
implicit def containerWriter[A: JsonFormat] = jsonFormat2(ListResponseObject.apply[A])
}

Related

How to create a generic Network Resource State classes in dart?

In Kotlin, I create generic classes to handle data fetching network states as following:
sealed class Resource<T>(
val data: T? = null,
val error: String? = null
) {
class Success<T>(data: T?) : Resource<T>(data)
class Loading<T> : Resource<T>()
class Error<T>(error: String) : Resource<T>(error = error)
}
Whenever I want to create an object of one of the available states, I can do that using Resource.Success<T> for example, not just Success<T>. I think this is a cleaner way to make my code easier to follow up with and understand.
I tried to achieve the same using dart, but I am stuck. I only created class the following way which is not really the same as what I want.
Can someone guide me on how to achieve my target using best practices?
abstract class ResourceState<T> {
T? data;
String? error;
ResourceState({this.data, this.error});
}
class ResourceLoading<T> extends ResourceState<T>{
ResourceLoading() : super();
}
class ResourceError extends ResourceState {
ResourceError(String error) : super(error: error);
}
class ResourceSuccess extends ResourceState {
ResourceSuccess(dynamic data) : super(data: data);
}
You will want to use named constructors:
class Resource<T> {
T ? data;
String? error;
Resource({this.data, this.error});
Resource.success(this.data);
Resource.error(this.error);
Resource.loading();
bool get isLoading => error == null && data == null;
bool get isSuccess => data != null;
bool get isError => error != null;
}
This allows you to create a success as Resource<T>.success(value) and an error as Resource<T>.error("Badness overwhelming!").
The type argument to the error constructor doesn't matter if you'll never add a data value. You could make it Resource<Never>.error("badness!").
I left the unnamed constructor public, in case you want to use it, but it's not necessary and can be removed.
If you want the class to really be sealed, you won't want any public generative (non-factory) constructors.
In that case, I'd do it as:
class Resource<T> {
T ? data;
String? error;
Resource._({this.data, this.error});
factory Resource.success(T data) => Resource._(data: data);
factory Resource.error(this.error) => Resource._(error: error);
factory Resource.loading() => Resource._();
// ...
}
This class cannot be extended because it has no public generative constructor available to do the super-constructor call that a subclass is require to do.
Its interface can still be implemented, because any Dart interface can.

How to use Sealed Class Data from Flow in Swift in Kotlin Mutliplatform Mobile?

I unable to access the sealed class data observed in a Flow from Swift ..
sealed class NetworkStatus<T> {
data class Loading<T>(var loading: Boolean) : NetworkStatus<T> ()
data class CustomSignal<T>(var signal: String) : NetworkStatus<T>()
data class CustomSignalDetailed<T>(var signal: ErrorCaseData) : NetworkStatus<T>()
data class Failure<T>(val e: Throwable) : NetworkStatus<T>()
data class Data<T> (val data: T ) : NetworkStatus<T>()
companion object {
fun <T>loading(isLoading: Boolean): NetworkStatus<T> = Loading(isLoading)
fun <T> customstatus(signal: String): NetworkStatus<T> = CustomSignal(signal)
fun <T> customStatusDetailed(signals: ErrorCaseData): NetworkStatus<T> = CustomSignalDetailed(signals)
fun <T> failure(e: Throwable): NetworkStatus<T> = Failure(e)
fun <T> data(data: T): NetworkStatus<T> = Data<T>(data)
}
}
https://gist.github.com/RageshAntony/a4fd357973485b5fb8aef0e189ee9e7e
In the above gist ....
In MainActivity.kt , I used sealed class in flow for Data
Now I need the same in Swift but it's confusing
Even I used something as CFlow wrapping.. still confusion
In Swift , I can't get object type only as nsarray and also NetworkStatus.data is not accessible
.. I tried manual typecast (in line 8 , contentview.swift )
Still data object don't have any type ...
Please help me how to implement the same flow in Swift like in MainActivity.kt
Start from this sealed class declared in the shared code:
sealed class KMMResult<out Value>
data class SuccessKMMResult<Value>(
val value: Value
): KMMResult<Value>()
data class ErrorKMMResult<Value>(
val throwable: Throwable
): KMMResult<Value>()
and this method that randomly returns you a KMMResult with Success or Failure:
fun getRandomIntWrappedInResult(): KMMResult<Int> {
val isSuccess = Random.nextBoolean()
return if(isSuccess) {
SuccessKMMResult(Random.nextInt(until = 10))
} else {
ErrorKMMResult(RuntimeException("There was an error, Int not generated"))
}
}
You can use it like this on Android:
val randomInt: KMMResult<Int> = getRandomIntWrappedInResult()
val randomIntText: String = when (randomInt) {
is KMMResult.ErrorKMMResult -> {
"Error: ${randomInt.throwable.message}"
}
is KMMResult.SuccessKMMResult -> {
"Success: ${randomInt.value}"
}
}
and like this on iOS:
let randomInt: KMMResult<KotlinInt> = RandomNumberGeneratorKt.getRandomIntWrappedInIntResult()
let randomIntText: String
switch randomInt {
case let error as KMMResultErrorKMMResult<KotlinInt>:
randomIntText = "Error: \(error.throwable.message ?? error.throwable.description())"
case let success as KMMResultSuccessKMMResult<KotlinInt>:
randomIntText = "Success: \(success.value)"
default:
randomIntText = "This never happens"
}
This is not the best solution, I suggest you to create a Swift enum like:
enum SwiftResult<Value> {
case error(String)
case success(Value)
}
and convert KMMResult to SwiftResult using:
func toSwiftResult<Value>(kmmResult: KMMResult<Value>) -> SwiftResult<Value> {
if let successResult = kmmResult as? KMMResultSuccessKMMResult<Value> {
return SwiftResult.success(successResult.value!)
}
if let errorResult = kmmResult as? KMMResultErrorKMMResult {
return SwiftResult.error(errorResult.throwable.message ?? errorResult.throwable.description())
}
return SwiftResult.error("Unexpected error converting to SwiftResult")
}
Unfortunately, you need to do this manually for each sealed class, so I suggest you to use the library moko-kswift that does this job for you.
P.S. Avoid use List<Something> as a generic type because Something will be erased and when seeing the type from Swift you will just see NSArray. You can use two classes, one for single item and one for List, still generic on Something, or you can create a wrapper data class around your list, say ListWrapper, so the type won't be erased, because your original List<Something> would be inside ListWrapper which will be the type for NetworkStatus.
So use NetworkStatus<ListWrapper<Something>> instead of NetworkStatus<List<Something>>
Another P.S. Your function getAllCategories() in the gist is returning a flow, so it shouldn't be a suspend function.

Effective implementation of generic matching Tokens

This is a base trait that I use in my tiny parser app:
trait Token[ValueType] {
def value: ValueType
}
This is what I require. I'd also like to combine a good feature of Java with a good feature of Scala i.e.:
Java approach to enums (they're normal objects with methods, can ihnerit etc.)
Scala suport for matching (readable code)
so an example of classes extending Token are:
// this to emulate Java enums; ProperEnumeration just adds some simple methods like fromChars etc.
object Keywords extends ProperEnumeration {
val AND, ARRAY, BEGIN, CASE, CONST, ... = Value
}
// this to enable matching
final case class Keyword(keyword: Keywords.Value) extends Token[Keywords.Value] {
def this(string: String) = this(Keywords.fromString(string))
def value = keyword
}
object SpecialSymbols extends ProperEnumeration {
val LEFT_BRACE = Value("{")
val RIGHT_BRACE = Value("}")
...
}
final case class SpecialSymbol(symbol: SpecialSymbols.Value) extends Token[SpecialSymbols.Value] {
def this(symbol: String) = this(SpecialSymbols.fromString(symbol))
def value = symbol
}
// there are also non-enum subclasses of Token
case class Identifier(identifier: String) extends Token[String] {
override def value: String = identifier
}
This is the best I came up with. I can use it like this:
token match {
case Keyword(Keywords.BEGIN) => ...
case SpecialSymbol(SpecialSymbols.LEFT_BRACE) => ...
case Identifier(name) => ...
}
I'd like to modify it to allow me to be more concise, I'd like something like this:
token match {
case Keyword.BEGIN => ... // or Keyword(BEGIN)
case SpecialSymbol.LEFT_BRACE => ...
case Identifier(name) => ...
}
to also suport a method called consume that would work with any kind of Token subclass (consume should throw an exception if the next token from source is NOT the argument supplied).
consume(Keyword.BEGIN);
consume(SpecialSymbol.LEFT_BRACE);
consume(Identifier(name));
I want the code to be clean, that's why I use Scala in the first place. So I hope for no function overloads to allow easy addition of Trait subclasses.
So, dear Scalists, what to do?
The simplest way to have
case Keyword(BEGIN) => ...
is to simply import the keywords:
import Keywords._
It won't require any other changes to your code.
However, I personally would prefer to avoid ProperEnumerarion and have a simple hierarchy of traits and case objects:
trait Keyword
case object BEGIN extends Keyword
case object CASE extends Keyword
This will automatically give pattern matching:
token match {
case BEGIN => ...
}
If you need some methods in objects you may have them declared in the trait of have some abstract class (with a constructor):
abstract class Keyword(val name:String) {
def myMethod = "Keyword."+name
}
case object BEGIN extends Keyword("BEGIN")
case object CASE extends Keyword("CASE")
UPD: You may use an object that instantiates "enum" instances the same way as Enumeration:
object AllMyKeywords {
val BEGIN = Keyword("BEGIN")
val CASE = Keyword("CASE")
// etc.
val values = List(BEGIN, CASE, ...).map(k => (k.name, k)).toMap
}
UPD2: There is also a way to make pattern matching with strings:
abstract class Keyword(val name:String) {
def unapply(str:String):Option[Keyword] = {
if(AllMyKeywords.values.contains(str))
Some(AllMyKeywords.values(str)
else
None
}
}
In this case the unapply method is implemented by every BEGIN, CASE keywords and thus it is directly called (at least I think so).
"BEGIN" match { case BEGIN => ??? }

grails replace method with an optional parameter by a closure

I have two class:
class Foo {
String doSomething(String a = 'Not working') {
return a
}
}
And I want to replace 'doSomething' in a test but it dosent work
#Test
void testMethodIWannaTest() {
Foo.metaClass.doSomething = {String a -> return 'Working'}
assert new Foo().doSomething() == 'Working' //THIS TEST FAIL, return 'Not Working'
}
If I remove the optional param, it works.
Did someone know how to fix this ?
*I know the test doesn't really make sens, it's just to show my point
What do I do wrong ? Is it possible to do it without using 'mockFor' ?
Setting a default parameter generates two methods:
String doSomething() { doSomething( 'Not working' ) }
String doSomething(String a) { a }
So try setting the no-arg function (as that's the one you're going to call:
Foo.metaClass.doSomething = { -> doSomething( 'Working' ) }

How can I use Reflection (Mirrors) to access the method names in a Dart Class?

I need to "fetch" the methods in a Dart Class.
How can I do this?
And I want to be able to call the methods.
May I see an example?
Here's an easy copy-pasteable code sample:
import 'dart:mirrors';
import 'dart:io';
main() {
var im = reflect(new File('test')); // Retrieve the InstanceMirror of some class instance.
im.type.methods.values.forEach((MethodMirror method) => print(method.simpleName));
}
Output is:
existsSync
_delete
exists
directory
_getDecodedLines
readAsTextSync
readAsBytesSync
readAsLinesSync
_directory
throwIfError
lastModifiedSync
readAsLines
open
_ensureFileService
deleteSync
delete
_exists
length
openInputStream
create
_create
readAsText
_openStdioSync
openOutputStream
_fullPath
_lastModified
fullPathSync
readAsBytes
lastModified
_openStdio
_open
openSync
lengthSync
directorySync
fullPath
createSync
_lengthFromName
Here is a basic example:
(Note: You will want to have a (very) up to date version of the SDK for this, this was done in Dart Editor version 0.2.1_r14167, Dart SDK version 0.2.1.2_r14167 Nov 2, 2012)
My most sincere Thanks to Gilad of the Google Dart Team for providing this example!
#import('dart:mirrors');
class MyClass {
String _test;
String get test => _test;
set test(String paramVal) => _test = paramVal;
void my_method() {
}
void print_test(){
print("test string is: ${_test}");
}
MyClass(String test) {
_test = test;
}
}
main() {
MyClass myClass = new MyClass("Make my day, PUNK.");
myClass.print_test();
//ClassMirror myClassMirror = reflect(myClass).type;
InstanceMirror myClassInstanceMirror = reflect(myClass);
ClassMirror MyClassMirror = myClassInstanceMirror.type;
Map<String, MethodMirror> map = MyClassMirror.methods;
print("map = ${map}");
map.values.forEach( (MethodMirror mm){
myClassInstanceMirror.invoke(mm.simpleName,[]);
});
}
Concerning Reflection I have just written a couple of "Helper Functions" for fetching a LIST of the method names (not a Map) and invoking the method... all I can say for sure is that it works right now. There are likely technical reasons for not doing it this way - but in my case this does not run in a complex environment. However, I do think they nicely mask over a lot of details that not everybody is going to want to deal with.
Here's a functioning demonstration with and without the Helper functions:
#import('dart:mirrors');
class MyClass {
String _test;
String get test => _test;
set test(String paramVal) => _test = paramVal;
void my_method1(){print("in method1");}
void my_method2(){print("in method2");}
void print_test(){
print("test string is: ${_test}");
}
MyClass(String test) {
_test = test;
}
}
//Helper Methods
InstanceMirror hMr;
List REFLECT_methods(Object myClass) {hMr=reflect(myClass);return(hMr.type.methods.values);}
REFLECT_invoke(MethodMirror mm){hMr.invoke(mm.simpleName, []);}
main() {
MyClass myClass = new MyClass("Make my day, PUNK.");
print("\n=======Using Raw Reflection================");
InstanceMirror myClassInstanceMirror = reflect(myClass);
ClassMirror MyClassMirror = myClassInstanceMirror.type;
Map<String, MethodMirror> map1 = MyClassMirror.methods;
map1.values.forEach( (MethodMirror mm){
myClassInstanceMirror.invoke(mm.simpleName,[]);
});
print("\n==========Using Helper functions=============");
List list2 = REFLECT_methods(myClass);
list2.forEach((method){
REFLECT_invoke(method);
});
}

Resources