How do get value in returned tuple - rust

I am having trouble with the returned value from Aave's Lending Pool V2 function getUserConfiguration() which returns a single tuple value ([value]), I can't seem to get this to work
err
InvalidOutputType("Expected `U256`, got Tuple([Uint(0)])")'
My code
let user_config:(U256,) = aave_lending_pool_contract.query("getUserConfiguration", *borrower, None, web3::contract::Options::default(), None).await.unwrap();
I have tried user_config:(Vec<U256>,) also but no luck. Any ideas?
==========
update, tried this
let (user_config_result) = aave_lending_pool_contract.query("getUserConfiguration", *borrower, None, web3::contract::Options::default(), None).await.unwrap();
let user_config = user_config_result.0;
println!("user config is {:?}", user_config);
still got the err
617 | ... let (user_config_result) = aave_lending_pool_contract.query("getUserConfiguration", *borrower, None, web3::contract::Options::default(), None).await.unwrap();
| ^^^^^^^^^^^^^^^^^^
618 | ... let user_config = user_config_result.0;
| ------------------ type must be known at this point

Related

Why does using a variable as a function parameter cause a type mismatch error in a later function call?

def make-list [val?: string] {
["f1" "f2"]
}
def use-list [list: list] {
$list | each { |it| $it + "!" }
}
let $val = "abc"
let $l = (make-list $val)
use-list $l
In this code, I have two functions, one to make a list, and another to consume that list. For the purposes of this MRE, make-list returns a simple hard-coded list, and use-list prints each element with an exclamation mark added to the end.
If this script executes correctly, it should print a list with two elements "f1!" and "f2!".
make-list has an optional parameter. In the code above, I create a $val variable, then pass that into make-list, and store the result of the pipeline to $l. Executing $l | describe instead of use-list $l prints list<string>, so I'm confident that $l is indeed a list.
The code above throws the following compile error:
Error: nu::parser::type_mismatch (link)
× Type mismatch.
╭─[/.../test.nu:10:1]
10 │ let $l = (make-list $val)
11 │ use-list $l
· ─┬
· ╰── expected List(Any), found String
╰────
However, I can modify the let $l ... line to allow the script to compile and execute correctly. Both of these options will allow the script to compile and returns the expected result.
The parameter for make-list can be removed (because the parameter is optional).
let $l = (make-list)
The parameter for make-list can be replaced by a string literal
let $l = (make-list "abc")
I don't understand why using a variable as a parameter call is suddenly causing a type issue with the use-list function call. What am I doing wrong here?
As an interesting side note, and this might explain the "...found String" part of the error message, if I change the make-list parameter to an int:
def make-list [val?: int] {
["f1" "f2"]
}
# ...
let $val = 3
let $l = (make-list $val)
use-list $l
It will fail to compile with the same kind of error, but the "found" type will reflect the updated parameter type.
Error: nu::parser::type_mismatch (link)
× Type mismatch.
╭─[/.../test.nu:10:1]
10 │ let $l = (make-list $val)
11 │ use-list $l
· ─┬
· ╰── expected List(Any), found Int
╰────
Tested using Nushell version 0.74.0 and 0.75.0 on Arch Linux and Windows 11, respectively.
Something seems to "go wrong" with the variable binding. Your scenario does work if the literal string is being evaluated in a subexpression before it is being bound:
let $val = ("abc")
# or
let $val = do { "abc" }
Even a seemingly useless type casting later on does the trick:
let $val = "abc"
let $l = (make-list ($val | into string))
This is also consistent with other types. Adapting your int example:
def make-list [val?: int] { … }
…
let $val = 123 # fails
let $val = (123) # works
Likewise, having a do closure, or type-casting using into int, do work as well.
Not of importance, however, is the syntax of the variable binding. With the $ sign omitted, all examples from above still work or fail under the same circumstances, e.g.:
let val = "abc" # fails
let val = ("abc") # works
As expected, using let l = instead of let $l = also yields the same results.

js_of_ocaml calling a function in ocaml from js

I have a function that uses a mutable variable that takes strings and returns strings. (its a read eval print loop interpreter)
I tried exporting it as such:
let () =
Js.export_all
(object%js
method js_run_repl = Js.wrap_callback js_run_repl
end)
Heres a snippet of the function im exporting
let js_run_repl str =
match String.(compare str "quit") with
| 0 -> "bye"
| _ -> ...
regardless of my input it always returns bye, calling the function directly in ocaml produced the expected behaviour. Heres the output from node:
> var mod = require('./main.bc');
undefined
> mod.js_run("constant P : Prop");
MlBytes { t: 0, c: 'bye', l: 3 }
>
Its also peculiar why the function is called js_run instead of js_run_repl. the latter is undefined according to node.
let () =
Js.export_all
(object%js
method js_run_repl str =
str
|> Js.to_string
|> js_run_repl
|> Js.string
end)
I had to convert the strings explicitly to ocaml strings and back to js

How do I properly handle AddressNotFound error from maxminddb::geoip2 in Rust?

I have a small piece of code that I need to fix and don't know much about Rust.
When I execute the following, it fail for certains ip values.
let city: geoip2::City = georeader.lookup(ip).unwrap();
let c_name = city.city
.and_then(|cy| cy.names)
.and_then(|n| n.get("en")
.map(String::from));
let loc = city.location.unwrap();
let lat = loc.latitude.unwrap();
let lon = loc.longitude.unwrap();
It fails with an AddressNotFound exception.
I tried to return a default value with
let city: geoip2::City = georeader.lookup(ip).unwrap_or_else(|err| geoip2::City::default(););
with it does not work nor address fully my problem.
In the end, I would like to catch AddressNotFound and set
let c_name = "unknown"
let loc = None
let lat = ""
let lon = ""
and use the actual value when available
let c_name = city.city
.and_then(|cy| cy.names)
.and_then(|n| n.get("en")
.map(String::from));
let loc = city.location.unwrap();
...
when the city is available.
I just don't know how to do such a thing in Rust. Could anyone point me to an quick example or helpme with that particular case?
Updated:
I took comments and tried the following:
let city: std::result::Result<Option<geoip2::City>, maxminddb::MaxMindDBError> = georeader.lookup(ip);
let (c_name, lat, lon) = match city {
Ok(Some(city)) => (
city.city.and_then(|cy| cy.names)
.and_then(|n| n.get("en")
.map(String::from)),
city.location.unwrap().latitude.unwrap(),
city.location.unwrap().longitude.unwrap()
),
_ => (Some("unknown".to_owned()), 0.0_f64, 0.0_f64),
};
I know have to find a way to use multiple city.location attributes in this context. I currently get this error:
error[E0382]: use of moved value: `city.location`
--> src/main.rs:93:15
|
92 | city.location.unwrap().latitude.unwrap(),
| ------------- value moved here
93 | city.location.unwrap().longitude.unwrap()
| ^^^^^^^^^^^^^ value used here after move
|
Maybe you can go like this, though I'm typing it from my head, so expect that it doesn't work right away
let (c_name, loc, lat, lon) = match city.city {
Ok(Some(names)) => (
names.get("en").to_string(),
city.location,
<something>,
<something>,
),
_ => ("unknown", None, "", ""),
}
Update:
First of all, entities like City and Location support Clone trait, so you can clone then instead of moving, but there's another dirty way using .as_ref() like that:
let city: std::result::Result<Option<geoip2::City>, maxminddb::MaxMindDBError> = georeader.lookup(ip);
let (c_name, lat, lon) = match city {
Ok(Some(city)) => (
city.city.and_then(|cy| cy.names)
.and_then(|n| n.get("en")
.map(String::from)),
city.location.as_ref().unwrap().latitude.unwrap(),
city.location.as_ref().unwrap().longitude.unwrap()
),
_ => (Some("unknown".to_owned()), 0.0_f64, 0.0_f64),
};

how to return a scarlar with let as method

I am trying to compare if an array is a subset of other and use it in another query. I could get the comparision method working. However, if I use the compare method in another query I get an error saying "Left and right side of the relational operator must be scalars" This hints that the comparearrays is not reutrning a scalar. Any ideas?
let x = parsejson('["a", "b", "c"]');
let y = parsejson('["a", "b", "c"]');
let z = parsejson('["b","a"]');
let comparearrays = (arr1:dynamic, arr2:dynamic)
{
let arr1Length = arraylength(arr1);
let total =
range s from 0 to arr1Length-1 step 1
| project dat = iff(arr1[s] in (arr2), true , false)
| where dat == true
| count;
total | extend isEqual= iff(Count == arr1Length,'true','false') | project
tostring(isEqual)
};
//comparearrays(z, x)
datatable (i:int) [4] | project i | where comparearrays(x,y) == 'true'
You are correct in your understanding - the current implementation returns a table with a single row and single column, but have no fear - toscalar to the rescue:
let x = parsejson('["a", "b", "c"]');
let y = parsejson('["a", "b", "c"]');
let z = parsejson('["b","a"]');
let comparearrays = (arr1:dynamic, arr2:dynamic)
{
let arr1Length = arraylength(arr1);
let result =
range s from 0 to arr1Length-1 step 1
| project dat = iff(arr1[s] in (arr2), true , false)
| where dat == true
| count
| extend isEqual = iff(Count == arr1Length,'true','false')
| project tostring(isEqual);
toscalar(result)
};
//comparearrays(z, x)
datatable (i:int) [4] | project i | where comparearrays(x,y) == 'true'
You do have a bug in the comparearrays functions, since comparearrays(z, x) returns true which is not correct....

Access variable from outside of the function in jQuery

Please see my exaple:
var AbcVar = "abc";
function Abc(AbcVar){
console.log(AbcVar);
}
It this wrong way to allowing function to access external var?
Why is the output of console.log undefined?
It's time to meet Mr. Scoping.
Plainly speaking, scoping is an encapsulation of variables (note that in javascript, functions are also variables.) Now, in the imaginary language I just made up, the { character starts a scope and } ends it, variables are defined with simple equality (x = 42 for example):
{ |
x = 42; |
{ | |
y = "I'm in an inner scope!"; | |
x == 42; //true | |
{ | | |
x == 42; | | |
y == "I'm in an inner scope!"; | | |
| x, y, z are defined |
z = "pyramid time!"; | | |
y = y + "...not"; | | x, y are defined | x is defined
} | | |
y == "I'm in an inner scope!...not"; | |
//z is not defined | |
x = 4; | |
} | |
x == 4; |
//y is undefined |
//z is undefined |
} |
javascript has lexical scoping. Put simply, functions create a new scope:
var x = 42;
(funciton () {
x === 42;
var y = 5;
})();
//y is undefined
Now, there's an additional place where variables can be created, and that is in the function arguments. The two following functions behave the same (arguments is a pseudo-array containing the parameters passed into the function):
function parameterfull(a, b, c) {
//do stuff with a, b, c
}
function parameterless() {
var a = arguments[0], b = arguments[1], c = arguments[2];
//do stuff with a, b, c
}
If you happen to not pass an argument, its value will be undefined.
Now, using your function and the above translation:
var AbcVar = "abc";
function Abc() {
var AbcVar = arguments[0];
console.log(AbcVar);
}
So now you see why AbcVar is (sometimes) undefined inside the function.
tl;dr The function parameter AbcVar is overriding the global variable AbcVar, and since you didn't pass a value to the function, it's undefined (but only inside of the function, the global AbcVar remains the same.)
Inside the function, AbcVar will refer to the parameter AbcVar of the function. If you don't pass any parameter, the value will be undefined.
The parameter shadows the variable in higher scope with the same name. If you want to access it, you have to remove or rename the parameter. That said, you should always prefer passing arguments to functions (where possible).
hi you can change this to
var AbcVar = "abc";
function Abc(bbb){
console.log(AbcVar);
}
you can access external global var,if you write inside function,it assume that like;
var AbcVar = "abc";
function Abc(var AbcVar){
console.log(AbcVar);
}
so inside funciton AbcVar is new vaiable and null ,it shadow global AbcVar
if you run the function you've just created and pass it your AbcVar,
console.log(AbcVar);
it loggs "abc" as expected
Consider the following code
var AbcVar = "abc";
function logVariable(passedIn){
console.log(passedIn);
}
logVariable(AbcVar);
which creates a variable, a function to log the value of the variable, and then passes the variable to the logger which loggs it in the console
If you notice two lines on your interactive console after you run your logger function: abc followed by undefined
the first is the line printed when you call console.log() and the second is the value that logVariable returns after executing, which is undefined on success.

Resources