Interactive instantiation of Enums and structs in Rust - struct

I know how to input strings from users, but I would like to input an enum:
enum DoneAction {
AddPassword {
entry: EntryInput,
result: Option<String>,
},
RemovePassword {
location: String,
result: Option<String>,
},
}
enum Action {
AddPassword,
RemovePassword,
Quit,
}
I would like to have something like this:
Please choose an action:
1: Add password
2: Remove a password
The program should loop if the user does not input 1 or 2:
Please input 1 or 2
And then, if the user inputs 1, I want to input a simple String, but if they input 2, I need to input three strings.
The program would ask for the location, then the identifier and the password.
I could implement the logic myself for this enum, but I would like to write something that can be used with different enums / structs.
Is there a procedural macro that I could use for this purpose?
Otherwise, is there another idiomatic way to do this?

Related

Resolve custom user condition from a collection - mongodb

The idea was that exercises should only be returned where applicable. All condition properties are stored in the user collection.
As an an example
exercises collection
title: string,
conditions?: [
{ property: string, // field from the user collection
operator: string, // (gt, eq, gte, lte, ...)
value: string
}
]
Each exercise can have one or more conditions.
It could look like this:
conditions: [
{ property: 'age',
operator: 'gte'
value: '18'
}
]
Current solution
With my current solution in the backend, I go through the result of mongodb and only return the one where the condition applies or is empty.
The problem
Unfortunately, that's not the best-performing solution.
.
Would that be possible with the aggregation framework?
Unfortunately, that overwhelms my aggregation knowledge.
Open for any solution ideas? :)
best regards

Joi apply different validation on nested object based on parent key

i just started using Joi and kind of lost about this case and don't know if its even possible the way i am going about it.
i have an object that has multiple keys with each key being a nested object with some shared props between them, something like this.
{
a: {
x: true,
y: ''
},
b: {
x: false
}
}
i am trying to make Joi validate that y exists when my parent is a and it should validate that y doesn't exist otherwise.
i am using pattern like this
const allowedKeys ['a', 'b']
Joi.object().pattern(
Joi.string().valid(...allowedKeys),
Joi.object().keys({
x: Joi.boolean(),
y: // this should exist if i am inside `a` but shouldn't otherwise
})
),
i have done a few searches and tried using alternatives, ref and when and a combo of them but i can't find a way to test the current parent key's value.
am i going about this correctly or should i follow another pattern to get what i need ?

Should send null or empty string value via body?

Should we send a null or empty string value on request ?
I mean we have an optional value and it had a value currently. If use want to delete value of that optional field, should API understand null or empty is delete value ?
Ex:
{
name: { type: String, required: true },
phone: { type: String, required: false }
}
In database:
{
name: "Alex",
phone: "012-333.222"
}
And now, use want to delete their phone number
Should we define looks like:
PUT /users/user-id-1
{
phone: null
}
Seems it's a bad convention
Should we send a null or empty string value on request ?
REST doesn't care; which is to say that it tells us to use self descriptive messages to transfer documents over a network, but it doesn't tell us what the representations of the documents should be.
Where you want to be looking instead is at message schema definitions, and in particular designing your schema in such a way that it can be extended in backwards compatible ways. The XML community spent a lot of time exploring those ideas; Orchard 2004 might be a good starting point.
In HTTP, the basic mechanism for describing a change to a resource is to use a PUT command with a copy of the new representation. So a request would probably look like:
PUT /users/user-id-1
Content-Type: application/json
{
name: "Alex",
phone: null
}
If your schema is defined in such a way that the phone field is optional, and that optional and null are equivalent (as opposed to some other implied value), then you might equivalently use:
PUT /users/user-id-1
Content-Type: application/json
{
name: "Alex"
}
In cases where the representation is very big, and the changes you are making are small, you might want to support PATCH.
PATCH /users/user-id-1
Content-Type: application/merge-patch+json
{
phone: null
}
Note that the HTTP PATCH specification includes the Allow-Patch which allows clients to discover which patch representations a server supports for a resource.
Though, in front end, usually it depends on whether use the delete button or, they just leave the field empty
phone: '' - means user left field empty
phone: null - means user click on delete field button. You decide whether to delete the field, or just set the document field to null.
I will usually delete the field, since it is now useless.
If you want to update only one property in a document you can use PATCH method instead of PUT method and your code should look like this:
PATCH /users/user-id-1
{
phone: ""
}

Resolving external string references ( IDs / "foreign keys" ) to structs present elsewhere in the same document, at deserialization time, with serde

I have Context objects - essentially a join record between a Cluster and a User - in a kubernetes config yaml ( ~/.kube/config ) i'd like to parse in to a struct that looks something like this:
struct Context {
name: String,
cluster: Cluster,
user: User
}
struct Cluster {
server: String
// ..
}
struct User {
name: String,
// ..
}
the yaml itself encodes these in to separate arrays, e.g.:
contexts:
- name: some_context
context:
cluster: some_cluster
user: some_user
clusters:
- name: some_cluster
cluster:
// many other, important fields ..
users:
- name: some_user
user:
// many other, important fields ..
i have no idea where to even begin with this - it seems as though i will need to have access to an interim representation of the document before i could "look ahead" to parse some of the complex structures in other parts of the document in to these structs external to Context
I've found the go-to kubernetes client crate is parsing this exact file, but it shies away from doing this and just provides the "raw" string keys
https://github.com/clux/kube-rs/blob/8c42f78ef86950baa17440fab992e39a12c5811b/kube/src/config/file_config.rs#L128
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Context {
pub cluster: String, // ideally cluster: Cluster
pub user: String, // ideally user: User
pub namespace: Option<String>,
pub extensions: Option<Vec<NamedExtension>>,
}
( comments in above snippet by me )
is there an example for how to do this serde?
I have thought about this a little longer and this may not be in scope for serde. I definitely found no way to do it currently.
Instead, I implemented a TryFrom between the low-level types with string id references, coming straight from serde, and my higher-level type with these references resolved.

Elixir: def structs with fields as lists of another struct type

If I have the following struct:
defmodule Events.InviteEvent do
defstruct [
:event_id,
:invite_list
]
end
Is it possible to define the :invite_list to be a list of which has a type of another struct ? Basically I would like to define a struct with the following structure:
{
event_id: 123,
invite_list: [
{name: "jason", email: "myemail1#email.com"},
{name: "judy", email: "myemail2#email.com"}
]
}
From Structs:
Structs provide compile-time guarantees that only the fields (and all of them) defined through defstruct will be allowed to exist in a struct
The only guarantee you get is that the field names are present. There is no way to specify the type of the values.
You could write a helper function to build your struct that uses typespecs, but that doesn't give you any extra compile-time or run-time guarantees.
In practice, I often add lists to my struct. So assuming you had an %Invite{} struct, I would write something like the following:
defmodule Events.InviteEvent do
defstruct [
event_id: nil,
invite_list: []
]
end
Then populate as you want.
%Events.InviteEvent{
event_id: 123,
invite_list: [
%Invite{name: "jason", email: "myemail1#email.com"},
%Invite{name: "judy", email: "myemail2#email.com"}
]
If you need to be careful that invite_list only contains a list of %Invite{}, then manage that with the interface to your struct.

Resources