swift 4.2 - how can I check with guard if a var has a valid enum value - enums

I need to check if a var, f.e. passed by a func, is a valid enum value. Not per se passed but just as an example here.
enum CollectionDict : String { // Mapping to String Model = "Model" or should I ...
case Model
case Type
case Element
case ....
}
....
guard InColectionDict != CollectionDict else { return false }
....
Obviously my sample guards line is wrong. What should I use or do to get the guard right or at least just compare/validate the InColectionDict variable with the enum CollectionDict in a one-liner?
I did hope to get away with..
func makeItem ( _ item: String , with key : String , inCollection : CollectionDict ) -> Bool {
guard let res = CollectionDict.inCollection else { return false }
But it give me an error.
Of course thank you in advance.

Swift is strongly typed. If your function has an non-optional Enum parameter, then at run-time it's guaranteed to be a valid enum value.

Related

How can I choose which struct member to update at runtime?

Say I have a struct in Go that looks like this:
LastUpdate struct {
Name string `yaml:"name"`
Address string `yaml:"address"`
Phone string `yaml:"phone"`
}
Now say I want to create a function that accepts the name of the field (eg. "Phone") and then updates that field to a value, like today's date.
How can I build the function in a way that it will accept the name of the field and update that field in the struct?
I know that I could do an IF clause for each scenario (if field == "Phone") {var.LastUpdate.Phone = time.Now().Date()}, but I'd like to build this function so that I don't have to go add an IF clause every time I add a new member to this struct in the future. Thoughts?
Use the reflect package to set a field by name.
// setFieldByName sets field with given name to specified value.
// The structPtr argument must be a pointer to a struct. The
// value argument must be assignable to the field.
func setFieldByName(structPtr interface{}, name string, value interface{}) error {
v := reflect.ValueOf(structPtr)
v = v.Elem() // deference pointer
v = v.FieldByName(name) // get field with specified name
if !v.IsValid() {
return errors.New("field not found")
}
v.Set(reflect.ValueOf(value))
return nil
}
Use it like this:
var lu LastUpdate
setFieldByName(&lu, "Name", "Russ Cox")
Run it on the Playground

Golang mock for all arguments except

mock.on("FunctionName", "someStringArgument").Return(...)
Suppose if someStringArgument is "hello" then I want to return "1". But if someStringArgument is any other string I want to return "2".
How is this achieve able with GoMock?
What you want to do is write a custom function which will return your desired output.
Here is a simple example of what I do.
Define a custom response function
func FunctionNameResponse(arg String) string{
if arg == "hellp" {
// I used quotes because you mentioned "1" and not 1
return "1"
}
return "2"
}
Call custom function anywhere needed.
mock.on("FunctionName", mock.Anything).Return(FunctionNameResponse("someStringArgument"))

How to pass different types as struct{} to function in GoLang?

I want to write a function that takes different struct-types as 1 parameter. Also, I have to be sure, that in these structs is an Id field. So I want a function like this:
MyFunction(object *struct{ Id int })
I tried it with passing the struct as a *struct{ Id int } and an interface{} parameter.
For example, I have these 2 struct-types:
type TableOne struct {
Id int
name string
date string
}
type TableTwo struct {
Id int
address string
athome bool
}
To save them in the database (using reflection) I have the following function:
func SaveMyTables(tablename string, obj *struct{ Id int }) {
// ... Some code here
if obj.Id != 0 {
// ... Some code here
}
// ... Some code here
}
I call the function like this:
obj := &TableTwo{
Id: 5
address: "some address"
athome: false
}
myPackage.Save("addresses", obj).
But I get this error:
cannot use obj (type *mytables.TableTwo) as type *struct { Id int } in argument to myPackage.Save
I want to write a function that takes different struct-types as 1 parameter. Also, I have to get sure, that in these struct is an Id field.
As of the current version of Go, you cannot do this. The only way Go supports passing multiple argument types to a single parameter is through the use of interfaces, and interfaces can only specify method sets, not fields.
(Go 2 plans to add generics, and this may be possible then. However, there's no concrete timeline for when that will be available.)

Initializing structures dynamically

I have a couple of structures, like:
type SomeObject struct {
sample int
}
I want to fill the sample variable based on what I get in the request body. To do this, I want to create a function, pass request body as a string to it, create an empty structure inside, fill the structure with data, return it, and replace chosen structure with this.
How do I do this? What do I return from the function? Is there a way to do this?
If you're dealing with multiple types then you should make your method return an interface{}. For all of the applicable types, create a convenience method like;
func NewSomeObject(reqBody string) *SomeObject {
return &SomeObject{sample:reqBody}
}
Which takes a string and returns a new instance of the type with that field set to whatever was passed in. Your question is missing information about how you determine which type should be instantiated but assuming you have a few, you'll likely need an if/else or a switch in the method which receives the request body so to give a very vague example it would be something like;
func ProcessRequest(reqBody string) interface{} {
if someCondition {
return NewSomeObject(reqBody)
} else if otherCondition {
return NewSomeOtherObject(reqBody)
} // potentially several other statements like this
return nil // catch all, if no conditions match
}
How about
func foo (s *SomeObject) {
s.sample = 123
}
or
func (s *SomeObject) foo() {
s.sample = 123
}

DART - can I cast a string to an enum?

Is there a way to convert a string to an enum?
enum eCommand{fred, joe, harry}
eCommand theCommand= cast(eCommand, 'joe');??
I think I just have to search for the enum (eg loop).
cheers
Steve
I got annoyed with the state of enums and built a library to handle this:
https://pub.dev/packages/enum_to_string
Basic usage:
import 'package:enum_to_string:enum_to_string.dart';
enum TestEnum { testValue1 };
main(){
final result = EnumToString.fromString(TestEnum.values, "testValue1");
// TestEnum.testValue1
}
Still more verbose than I would like, but gets the job done.
I have came up with a solution inspired from https://pub.dev/packages/enum_to_string that can be used as a simple extension on List
extension EnumTransform on List {
String string<T>(T value) {
if (value == null || (isEmpty)) return null;
var occurence = singleWhere(
(enumItem) => enumItem.toString() == value.toString(),
orElse: () => null);
if (occurence == null) return null;
return occurence.toString().split('.').last;
}
T enumFromString<T>(String value) {
return firstWhere((type) => type.toString().split('.').last == value,
orElse: () => null);
}
}
Usage
enum enum Color {
red,
green,
blue,
}
var colorEnum = Color.values.enumFromString('red');
var colorString: Color.values.string(Color.red)
Dart 2.6 introduces methods on enum types. It's much better to call a getter on the Topic or String itself to get the corresponding conversion via a named extension. I prefer this technique because I don't need to import a new package, saving memory and solving the problem with OOP.
I also get a compiler warning when I update the enum with more cases when I don't use default, since I am not handling the switch exhaustively.
Here's an example of that:
enum Topic { none, computing, general }
extension TopicString on String {
Topic get topic {
switch (this) {
case 'computing':
return Topic.computing;
case 'general':
return Topic.general;
case 'none':
return Topic.none;
}
}
}
extension TopicExtension on Topic {
String get string {
switch (this) {
case Topic.computing:
return 'computing';
case Topic.general:
return 'general';
case Topic.none:
return 'none';
}
}
}
This is really easy to use and understand, since I don't create any extra classes for conversion:
var topic = Topic.none;
final string = topic.string;
topic = string.topic;
(-:
As of Dart 2.15, you can use the name property and the byName() method:
enum eCommand { fred, joe, harry }
eCommand comm = eCommand.fred;
assert(comm.name == "fred");
assert(eCommand.values.byName("fred") == comm);
Just be aware that the byName method throws an ArgumentError if the string is not recognized as a valid member in the enumeration.
For the Dart enum this is a bit cumbersome.
See Enum from String for a solution.
If you need more than the most basic features of an enum it's usually better to use old-style enums - a class with const members.
See How can I build an enum with Dart? for old-style enums
This is the fastest way I found to do this :
enum Vegetable { EGGPLANT, CARROT, TOMATO }
Vegetable _getVegetableEnum(dynamic myVegetableObject) {
return Vegetable.values.firstWhere((e) => describeEnum(e) == myVegetableObject);
}
i had the same problem, a small enum and a string, so i did this
dynamic _enum_value = EnumFromString(MyEnum.values, string_to_enum);
dynamic EnumFromString(List values, String comp){
dynamic enumValue = null;
values.forEach((item) {
if(item.toString() == comp){
enumValue = item;
}
});
return enumValue;
}
i know this is not the best solution, but it works.
Static extension methods would make this nice (currently unimplemented).
Then you could have something like this:
extension Value on Keyword {
/// Returns the valid string representation of a [Keyword].
String value() => toString().replaceFirst(r'Keyword.$', '');
/// Returns a [Keyword] for a valid string representation, such as "if" or "class".
static Keyword toEnum(String asString) =>
Keyword.values.firstWhere((kw) => kw.value() == asString);
}
FOUND ANS
Check this article. Very well explained: Link
extension EnumParser on String {
T toEnum<T>(List<T> values) {
return values.firstWhere(
(e) => e.toString().toLowerCase().split(".").last ==
'$this'.toLowerCase(),
orElse: () => null,
),
}
}
The cleanest way is to use built-in functionality:
enum EmailStatus {
accepted,
rejected,
delivered,
failed,
}
EmailStatus.values.byName('failed') == EmailStatus.failed;
=> true

Resources