syn::Field.attrs doesn't contain inert attributes - rust

Given the following struct definition:
#[derive(Builder)]
pub struct Command {
executable: String,
#[builder(each = "arg")]
args: Vec<String>,
#[builder(each = "env")]
env: Vec<String>,
current_dir: Option<String>,
}
(where the #[builder(...)] attributes are inert attributes defined by my Builder derive macro implementation),
the Builder macro cannot "see" the #[builder(...)] field attributes. The following code
let name = &f.ident;
let attrs = &f.attrs;
println!("Attributes: {:?}: {}", name, attrs.len());
(where f is a syn::Field) gives
Attributes: Some(Ident { ident: "executable", span: #0 bytes(2830..2840) }): 0
Attributes: Some(Ident { ident: "args", span: #0 bytes(2854..2858) }): 0
Attributes: Some(Ident { ident: "env", span: #0 bytes(2877..2880) }): 0
Attributes: Some(Ident { ident: "current_dir", span: #0 bytes(2899..2910) }): 0
(Full code: https://github.com/pdkovacs/forked-proc-macro-workshop/blob/a471007968f974ea3c1c684cc47a77fbd20b91dc/builder/src/lib.rs)
Can anybody help me find out what I am missing here, please?

I think you might just be interpreting the terminal output incorrectly since when I cloned your fork and removed the test code that failed to compile this is the output I got for the test with the attributes:
test tests/07-repeated-field.rs ... ok
WARNINGS:
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
warning: unused import: `builder_trait:: Builder`
--> tests/07-repeated-field.rs:32:5
|
32 | use builder_trait:: Builder;
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: 1 warning emitted
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
STDOUT:
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
Attributes: Some(Ident { ident: "executable", span: #0 bytes(1471..1481) }): 0
Attributes: Some(Ident { ident: "args", span: #0 bytes(1524..1528) }): 1
Attributes: Some(Ident { ident: "env", span: #0 bytes(1576..1579) }): 1
Attributes: Some(Ident { ident: "current_dir", span: #0 bytes(1598..1609) }): 0
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
STDERR:
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
warning: unused import: `builder_trait:: Builder`
--> /home/cassy/projects/forked-proc-macro-workshop/builder/tests/07-repeated-field.rs:32:5
|
32 | use builder_trait:: Builder;
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
To be clear I completely commented out the body of main in 07-repeated-field.rs since it was failing to compile, and doing so allowed me to see this output.
I haven't used trybuild before but it seems like if a test fails to build then it doesn't give you the output from the proc macro invocation. Moreover it displays the STDOUT/STDERR of the test compilation process after it displays the test name, which likely was the source of the confusion.

Related

How to use a float as an env var in cargo/rust?

Like the title suggests, how can I create an env variable in cargo that is of type float?
I have a created .cargo/config.toml file and would like to add all the game related env variables like so:
[env]
test = "testtingggg"
yo = "yoyoyoyoyoyo"
game_zero_level = "hello"
game_zero_multiplier = 0.1
# game_one_level = 1
# game_one_multiplier = 1.0
# game_two_level = 2
# game_two_multiplier = 2.5
# game_three_level = 3
# game_three_multiplier = 5.0
# game_four_level = 3
#[derive(Serialize, Deserialize, Debug)]
pub struct Config {
pub level_zero: LevelZero,
pub level_one: LevelOne,
pub level_two: LevelTwo,
pub level_three: LevelThree,
pub level_four: LevelFour,
}
impl Config {
pub fn new() -> Self {
// Get env variables
let temp = option_env!("game_zero_level").unwrap();
msg!("simple env read for first game...");
msg!("{}", temp);
// load them into struct
// template for now
Config {
level_zero: LevelZero { level: 0, multiplier: 1.0 },
level_one: LevelOne { level: 1, multiplier: 1.0 },
level_two: LevelTwo { level: 2, multiplier: 1.0 },
level_three: LevelThree { level: 3, multiplier: 1.0 },
level_four: LevelFour { level: 4, multiplier: 1.0 },
}
}
}
Code
However, I got an error:
2022-12-24T18:22:59.802122509Z ERROR cargo_build_sbf] Failed to obtain packag
e metadata: `cargo metadata` exited with an error: error: could not load Cargo
configuration
Caused by:
failed to load TOML configuration from `/home/tai/Code/solana/techniques
/env-vars3/programs/env-vars3/.cargo/config.toml`
Caused by:
failed to parse key `env`
Caused by:
failed to parse key `game_zero_multiplier`
Caused by:
found TOML configuration value of unknown type `float`
error
Any suggestions would be soo appreciated! Thanks

Using Nipplejs in Vue with Quasar

i am trying to use Nipplejs in my Vue Project with quasar Components.
I installed nipplejs by npm install nipplejs --save.
I tried to integrate the nipple with the following code:
<template>
<div id="joystick_zone"></div>
</template>
<script lang= "ts">
// Imports
import Vue from "vue";
import nipplejs from 'nipplejs';
export default Vue.extend({
async mounted(): Promise<void> {
var options = {
zone: document.getElementById('joystick_zone') as HTMLElement,
mode: 'static',
color: `'blue'`,
}
var manager = nipplejs.create(options);
}
});
My first problem is that typescript doesnt accept 'static' as mode:
The definition says: mode?: 'dynamic' | 'semi' | 'static';
And i get the following error message:
Argument of type '{ zone: HTMLElement; mode: string; color: string; }' is not assignable to parameter of type 'JoystickManagerOptions'.
Types of property 'mode' are incompatible.
Type 'string' is not assignable to type '"dynamic" | "semi" | "static" | undefined'.
My second problem is that the joystick does not appear on the website.
If someone could help i would be very thankful.
If you would look into the definition of options variable you created. You would see it is of type { zone: HTMLElement; mode: string; color: string; }.
You must assign a type to the options variable.
var options: JoystickManagerOptions = {
zone: document.getElementById('joystick_zone') as HTMLElement,
mode: 'static',
color: 'blue',
};
Other option is to define the variable as const:
var options = {
zone: document.getElementById('joystick_zone') as HTMLElement,
mode: 'static',
color: 'blue',
} as const;
// Variable is now of type
type options = {
zone: HTMLElementHTMLElement;
mode: 'static';
color: 'blue';
}

How to configure ACPI *.asl for a virtual mdio-gpio device connected to a I2C gpio expander

I'm working with a Q7 Module (x86) and try to configure our peripherals with ACPI SSDT Overlay on Linux. But I strugle with it. I think I missunderstand some of the core concept of ACPI.
Problem
CPU -> I2C -> PCA9575 GPIO Expander -> virtual,mdio-gpio -> Ethernet Phy
What works
DefinitionBlock ("abc.asl", "SSDT", 2, "test", "HAL", 2)
{
External (\_SB_.PCI0.D01D, DeviceObj)
Scope (\_SB.PCI0.D01D)
{
Device (ABC0)
{
Name (_HID, "PRP0001") // must be PRP0001 that linux searches for compatible driver
Name (_CRS, ResourceTemplate () {
I2cSerialBusV2 (
0x20, // SlaveAddress : I2C Address
ControllerInitiated, // SlaveMode : ControllerInitiated
100000, // ConnectionSpeed : max Bus Speed for this device
AddressingMode7Bit, // AddressingMode : Adress Mode
"\\_SB.PCI0.D01D", // ResourceSource : I2C host controller
0x00, // ResourceSourceIndex : must be 0
ResourceConsumer, // ResourceUsage : must be ResourceConsumer
, // DescriptorName : optional name for integer value which is an offset to a buffer field...
Exclusive // Shared : Shared or Exclusive
,) // VendorData : optional field
})
Name (_DSD, Package() {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package (2) { "compatible", "nxp,pca9575" },
Package () { "gpio-line-names", Package ()
{ "LED_Red",
"",
"MDC",
"MDIO",
}
},
},
ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
Package () {
Package () { "led-red", "LED0" },
Package () { "mdc-gpios", "MDC0" },
Package () { "mdio-gpios", "MDIO" },
}
})
Name (LED0, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"gpio-hog", 1},
Package () {"gpios", Package () {0, 1}},
Package () {"output-low", 1},
}
})
... <placeholder for virtual,mdio-gpiocode here> ...
}
}
}
It recognises the PCA9575 GPIO expander and registering it as gpiochip in Linux. The LED is fixed to low and "hogged". It seems that this part is not totally wrong.
What not works
I inserted this code into the placeholder
Device (MD00)
{
Name (_HID, "PRP0001") // must be PRP0001 that linux searches for compatible driver
Name (_DSD, Package() {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package (2) { "compatible", "virtual,mdio-gpio" },
Package () {"gpios", Package () {^MDC0, 2, 0,
^MDIO, 3, 0,}},
}
})
}
But when I try to load this file via configfs I can see an error message in dmesg that the compatible field for the defined resource in _CRS field is missing. But I don't even defined a _CRS field.
I'm also not sure if my GPIO's are defined correctly. I'm not able to set the Pull-Modes with the Package () {"gpios", Package () {0, 1}}, command.
I question myself, shall the GPIO Expander Ports again defined as GgioIo Structures in the MDO Device?
Name (_CRS, ResourceTemplate () {
GpioIo (Exclusive, PullNone, 0, 0, IoRestrictionNone,
"\\_SB.PCI0.D01D.ABC0", 0, ResourceConsumer) {2}
GpioIo (Exclusive, PullNone, 0, 0, IoRestrictionNone,
"\\_SB.PCI0.D01D.ABC0", 0, ResourceConsumer) {3}
})
It doesn't seem to work either and I'm confused. I'm not sure if I use the GPIO PCA9575 driver correctly. Where could I configure the pull bias in ACPI? The driver load the config from of_ but I don't know where to define it in ACPI. I hope somebody here got an idea.
First of all let's see the main architecture of the design:
+-------------------+
| HOST | +------+
| MDIO <------>+ MDIO |
| Intf | | Phy |
| | +--^---+
| +------+ | | +-----+
| | I²C | | | | LED |
| | host | | | +--^--+
| +--^---+ | | |
| | | +--+---+ |
+-------------------+ | I²C | |
+----------------------> GPIO +------+
+------+
From this schematic we see how devices are related to each other. Now let's move to ACPI representation. At the beginning we need to define I²C GPIO expander. From the examples in meta-acpi project we can find how PCA9535 can be described. Assuming we found the I²C host controller device (\_SB_.PCI0.D01D as per your post) and the fact that you have expander without latching IRQ events, the following is the mix between original ASL excerpt and how to match it with proper configuration in the driver:
Device (ABC0)
{
Name (_HID, "PRP0001")
Name (_DDN, "NXP PCA9575 GPIO expander")
Name (RBUF, ResourceTemplate()
{
I2cSerialBusV2(0x0020, ControllerInitiated, 400000,
AddressingMode7Bit, "\\_SB.PCI0.D01D",
0x00, ResourceConsumer, , Exclusive, )
})
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"compatible", "nxp,pca9575"},
Package () {"gpio-line-names", Package () {
"LED_Red",
"",
"MDC",
"MDIO",
}},
}
})
Method (_CRS, 0, NotSerialized)
{
Return (RBUF)
}
Method (_STA, 0, NotSerialized)
{
Return (0x0F)
}
}
This excerpt provides us a new GPIO chip in the system, resources of which can be consumed by others.
For example, in your Virtual MDIO Phy case (see _DSD Device Properties Related to GPIO as well)
Device (MD00)
{
Name (_HID, "PRP0001")
Name (_CRS, ResourceTemplate () {
GpioIo (Exclusive, PullDown, 0, 0, IoRestrictionOutputOnly,
"\\_SB.PCI0.D01D.ABC0", 0, ResourceConsumer) {2} // pin 2
GpioIo (Exclusive, PullDown, 0, 0, IoRestrictionOutputOnly,
"\\_SB.PCI0.D01D.ABC0", 0, ResourceConsumer) {3} // pin 3
})
Name (_DSD, Package() {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () { "compatible", "virtual,mdio-gpio" },
Package () {
"gpios", Package () {
^MD00, 0, 0, 0, // index 0 in _CRS -> pin 2
^MD00, 1, 0, 0, // index 1 in _CRS -> pin 3
}
},
}
})
}
Now it is a time to look at the LED binding code. For the sake of clarification hogging is when you want a GPIO provider to consume a resource itself. And it is quite likely not your case. Better is to connect this with the LED GPIO driver:
Device (LEDS)
{
Name (_HID, "PRP0001")
Name (_DDN, "GPIO LEDs device")
Name (_CRS, ResourceTemplate () {
GpioIo (
Exclusive, // Not shared
PullUp, // Default off
0, // Debounce timeout
0, // Drive strength
IoRestrictionOutputOnly, // Only used as output
"\\_SB.PCI0.D01D.ABC0", // GPIO controller
0) // Must be 0
{
0, // LED_Red
}
})
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () { "compatible", Package() { "gpio-leds" } },
},
ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
Package () {
Package () { "led-0", "LED0" },
}
})
/*
* For more information about these bindings see:
* Documentation/devicetree/bindings/leds/common.yaml,
* Documentation/devicetree/bindings/leds/leds-gpio.yaml and
* Documentation/firmware-guide/acpi/gpio-properties.rst.
*/
Name (LED0, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () { "label", "red" },
Package () { "default-state", "on" },
Package () { "gpios", Package () { ^LEDS, 0, 0, 1 } }, // active low
}
})
}
Also you may look into similar questions (starting from the given link and there are references to the rest) on StackOverflow site.

yargs warning: Too many arguments provided. Expected max 1 but received 2

I have an issue with my yargs configuration:
const argv = require('yargs')
.boolean('reset', {
alias: 'rs'
})
.boolean('refreshConfig', {
alias: 'rc'
})
.option('harvest', {
alias: 'h'
})
.option('lang', {
alias: 'l',
default: 'fr'
})
.help().argv;
I executed the script as below:
$ node ./srcjobs/cli.js --refreshConfig --harvest=facebook
and I received this error:
Too many arguments provided. Expected max 1 but received 2.
Do you know why ?
Thank you for your help.
.boolean receive only 1 argument, from source code
boolean<K extends string>(key: K | ReadonlyArray<K>): Argv<T & { [key in K]: boolean | undefined }>;
Proper way
const argv = require('yargs')
.boolean('reset')
.alias('rs', 'reset')
.boolean('refreshConfig')
.alias('rc', 'refreshConfig')
.option('harvest', {
alias: 'h'
})
.option('lang', {
alias: 'l',
default: 'fr'
})
.help().argv;

Digital Asset Node.js bindings: syntax for expressing 'time' type variable

I am working through the tutorial where it says how to create a contract.
Here is their code:
function createFirstPing() {
const request = {
commands: {
applicationId: 'PingPongApp',
workflowId: `Ping-${sender}`,
commandId: uuidv4(),
ledgerEffectiveTime: { seconds: 0, nanoseconds: 0 },
maximumRecordTime: { seconds: 5, nanoseconds: 0 },
party: sender,
list: [
{
create: {
templateId: PING,
arguments: {
fields: {
sender: { party: sender },
receiver: { party: receiver },
count: { int64: 0 }
}
}
}
}
]
}
};
client.commandClient.submitAndWait(request, (error, _) => {
if (error) throw error;
console.log(`Created Ping contract from ${sender} to ${receiver}.`);
});
}
I want to create a similar request for in my project that sends a field called 'datetime_added'. In my DAML code it is of type time. I cannot figure out the proper syntax for this request. For example:
arguments: {
fields: {
sender: { party: sender },
receiver: { party: receiver },
count: { int64: 0 },
datetime_added: { time: '2019 Feb 19 00 00 00' }
}
}
The format I am expressing the time is not what is causing the problem (although I acknowledge that it's also probably wrong). The error I'm seeing is the following:
Error: ! Validation error
▸ commands
▸ list
▸ 0
▸ create
▸ arguments
▸ fields
▸ datetime_added
✗ Unexpected key time found
at CommandClient.exports.SimpleReporter [as reporter] (/home/vantage/damlprojects/loaner_car/node_modules/#da/daml-ledger/lib/data/reporting/simple_reporter.js:36:12)
at Immediate.<anonymous> (/home/vantage/damlprojects/loaner_car/node_modules/#da/daml-ledger/lib/data/client/command_client.js:52:62)
at runCallback (timers.js:705:18)
at tryOnImmediate (timers.js:676:5)
at processImmediate (timers.js:658:5)
I don't understand, is time not a valid DAML data type?
Edit
I tried switching time to timestamp as follows
datetime_added: {timestamp: { seconds: 0, nanoseconds: 0 }}
causing the following error:
/home/......../damlprojects/car/node_modules/google-protobuf/google-protobuf.js:98
goog.string.splitLimit=function(a,b,c){a=a.split(b);for(var d=[];0<c&&a.length;)d.push(a.shift()),c--;a.length&&d.push(a.join(b));return d};goog.string.editDistance=function(a,b){var c=[],d=[];if(a==b)return 0;if(!a.length||!b.length)return Math.max(a.length,b.length);for(var e=0;e<b.length+1;e++)c[e]=e;for(e=0;e<a.length;e++){d[0]=e+1;for(var f=0;f<b.length;f++)d[f+1]=Math.min(d[f]+1,c[f+1]+1,c[f]+Number(a[e]!=b[f]));for(f=0;f<c.length;f++)c[f]=d[f]}return d[b.length]};goog.asserts={};goog.asserts.ENABLE_ASSERTS=goog.DEBUG;goog.asserts.AssertionError=function(a,b){b.unshift(a);goog.debug.Error.call(this,goog.string.subs.apply(null,b));b.shift();this.messagePattern=a};goog.inherits(goog.asserts.AssertionError,goog.debug.Error);goog.asserts.AssertionError.prototype.name="AssertionError";goog.asserts.DEFAULT_ERROR_HANDLER=function(a){throw a;};goog.asserts.errorHandler_=goog.asserts.DEFAULT_ERROR_HANDLER;
AssertionError: Assertion failed
at new goog.asserts.AssertionError (/home/vantage/damlprojects/loaner_car/node_modules/google-protobuf/google-protobuf.js:98:603)
at Object.goog.asserts.doAssertFailure_ (/home/vantage/damlprojects/loaner_car/node_modules/google-protobuf/google-protobuf.js:99:126)
at Object.goog.asserts.assert (/home/vantage/damlprojects/loaner_car/node_modules/google-protobuf/google-protobuf.js:99:385)
at jspb.BinaryWriter.writeSfixed64 (/home/vantage/damlprojects/loaner_car/node_modules/google-protobuf/google-protobuf.js:338:80)
at proto.com.digitalasset.ledger.api.v1.Value.serializeBinaryToWriter (/home/vantage/damlprojects/loaner_car/node_modules/#da/daml-ledger/lib/grpc/generated/com/digitalasset/ledger/api/v1/value_pb.js:289:12)
at jspb.BinaryWriter.writeMessage (/home/vantage/damlprojects/loaner_car/node_modules/google-protobuf/google-protobuf.js:341:342)
at proto.com.digitalasset.ledger.api.v1.RecordField.serializeBinaryToWriter (/home/vantage/damlprojects/loaner_car/node_modules/#da/daml-ledger/lib/grpc/generated/com/digitalasset/ledger/api/v1/value_pb.js:1024:12)
at jspb.BinaryWriter.writeRepeatedMessage (/home/vantage/damlprojects/loaner_car/node_modules/google-protobuf/google-protobuf.js:350:385)
at proto.com.digitalasset.ledger.api.v1.Record.serializeBinaryToWriter (/home/vantage/damlprojects/loaner_car/node_modules/#da/daml-ledger/lib/grpc/generated/com/digitalasset/ledger/api/v1/value_pb.js:822:12)
at jspb.BinaryWriter.writeMessage (/home/vantage/damlprojects/loaner_car/node_modules/google-protobuf/google-protobuf.js:341:342)
In short, I need to know what type to use in my Node.js client for a DAML value of type time and how to express it.
I would recommend using the reference documentation for the bindings (although, as of version 0.4.0, browsing through it to answer your question I noticed two mistakes). In the upper navigation bar of the page you can start from Classes > data.CommandClient and work your way down its only argument (SubmitAndWaitRequest) until, following the links to the different fields, you reach the documentation for the timestamp field, which, as the error suggests (despite the mistake in the documentation), should be a Timestamp, where seconds are expressed in epoch time (seconds since 1970).
Hence, to make the call you wanted this would be the shape of the object you ought to send:
arguments: {
fields: {
sender: { party: sender },
receiver: { party: receiver },
count: { int64: 0 }
datetime_added: { timestamp: { seconds: 0, nanoseconds: 0 } }
}
}
For your case in particular, I would probably make a small helper that uses the Date.parse function.
function parseTimestamp(string) {
return { seconds: Date.parse(string) / 1000, nanoseconds: 0 };
}
That you can then use to pass in the time you mentioned in the example you made:
arguments: {
fields: {
sender: { party: sender },
receiver: { party: receiver },
count: { int64: 0 }
datetime_added: { timestamp: parseTimestamp('2019-02-19') }
}
}
As a closing note, I'd like to add that the Node.js bindings ship with typing files that provide auto-completion and contextual help on compatible editors (like Visual Studio Code). Using those will probably help you. Since the bindings are written in TypeScript, the typings are guaranteed to be always up to date with the API. Note that for the time being, the auto-completion works for the Ledger API itself but won't give you help for arbitrary records that target your DAML model (the fields object in this case).

Resources