Closed xiusin closed 8 months ago
Does it fail when compiling? Or is this just a question about what's displayed in vscode/codeium/whatever editor that is?
@JalonSolov Compilation can also fail, reminding and editors should be consistent.
Make sure you didn't make a typo: AccountPostion AccountPosition
pub fn (mut api App) api_account_position() vweb.Result {
mut postions := []AccountPostion{} // some items // <== AccountPostion ???
for i, mut postion in postions {
postion.recid = postion.inst_id
if postion.mgn_ratio.f64() * 100 <= 300 {
postion.w2ui.style = 'background-color: #f3d6e3'
} else if postion.upl_ratio.f64() * 100 < -50 {
postion.w2ui.style = 'background-color: rgb(242, 250, 140)'
} else {
mut ratio := 0
if postion.lever.f64() >= 20 {
ratio = 50
} else if postion.lever.f64() >= 10 {
ratio = 30
} else if postion.lever.f64() >= 3 {
ratio = 20
}
if postion.upl_ratio.f64() * 100 > ratio {
postion.w2ui.style = 'background-color: #C2F5B4'
}
}
postions[i] = postion
}
request := api.query['request'] or { '{}' }
dto := json.decode(RequestDto, request) or { RequestDto{} }
// If you use sort_with_compare, it will report an error on the last line
postions.sort_with_compare(fn [dto] (a &AccountPosition, b &AccountPosition) int { // <== AccountPosition ???
if dto.sort.len == 0 {
return 0
}
mut left := ''
mut right := ''
left, right = match dto.sort[0].field {
'uplRatio' {
a.upl_ratio, b.upl_ratio
}
'upl' {
a.upl, b.upl
}
else {
'', ''
}
}
if left == right {
return 0
}
if dto.sort[0].direction == 'desc' {
return if left < right { -1 } else { 1 }
} else {
return if left > right { -1 } else { 1 }
}
})
return api.json(postions) <- here
}
@shove70 The code above is written manually by me, and there are some mistakes in it.
struct AccountPosition {
adl string @[omitempty]
...
}
v run main.v
main.v:236:9: error: undefined ident: `api` 234 | }) 235 | 236 | return api.json(postions) | ~~~ 237 | } 238 | main.v:236:13: error: cannot call a method using an invalid expression 234 | }) 235 | 236 | return api.json(postions) | ~~~~~~~~~~~~~~ 237 | } 238 | main.v:236:2: error: `api.json(postions)` used as value 234 | }) 235 | 236 | return api.json(postions) | ~~~~~~~~~~~~~~~~~~~~~~~~~ 237 | } 238 |
Whether this word is wrong or not, take a look at the 2 inconsistencies I've highlighted in your code.
With the correct change, 'postions.sort_with_compare' does not affect compilation!
@shove70 Oh, it might be my version issue. Let me try again. Thank you.
@shove70 If you use the following code, you will encounter compilation errors
postions.sort_with_compare(fn [dto] (a &AccountPosition, b &AccountPosition) int // failed
postions.sort_with_compare(fn (a &AccountPosition, b &AccountPosition) int // success
It will report the error of the next function
243 |
244 | @['/api/account/balance'; get]
245 | pub fn (mut api App) api_account_balance() vweb.Result {
| ~~~
246 | data := api.get_account_balance() or { return api.failed(err) }
247 | return api.json(data)
Currently, there seems to be a compilation issue when capturing external variables.
Can you reproduce bugs by making your code as simple as possible? And provide the error information of V report as much as possible, thank you.
In general, when reporting a BUG, you should try to provide the simplest but complete code and pinpoint the core problem so that the developer can fix it quickly.
On the other hand, if the developer has to guess, progress can be very slow.
import vweb
import json
struct App {
vweb.Context
}
struct AccountPosition {}
struct RequestDto {}
struct Balance {}
pub fn (mut api App) api_account_position() vweb.Result {
mut postions := []AccountPosition{}
request := api.query['request'] or { '{}' }
dto := json.decode(RequestDto, request) or { RequestDto{} }
postions.sort_with_compare(fn [dto] (a &AccountPosition, b &AccountPosition) int {
println(dto)
return 0
})
return api.json(postions)
}
@['/api/account/balance'; get]
pub fn (mut api App) api_account_balance() vweb.Result {
data := Balance {}
return api.json(data)
}
This code does not report any issues with the closure parameter capture, compiles correctly, and does not affect the next function.
@shove70 The following code cannot be compiled
module main
import os
import net.http
import json
import vweb
import db.sqlite
struct Api {
vweb.Context
domain string = 'https://demo.baidu.com'
key string @[vweb_global]
secret string @[vweb_global]
passpharse string @[vweb_global]
pub mut:
db sqlite.DB
}
@[table: 'okx_position_items']
struct OkxPositionItemModel {
id int @[primary; sql: serial]
inst_id string @[sql_type: 'TEXT']
inst_type string @[sql_type: 'TEXT']
star bool @[sql_type: 'INTEGER']
}
pub fn Api.new(key string, secret string, passphrase string) !&Api {
mut api := &Api{
key: key
secret: secret
passpharse: passphrase
db: sqlite.connect(':memory:')!
}
api.db.synchronization_mode(sqlite.SyncMode.off)!
api.db.journal_mode(sqlite.JournalMode.memory)!
sql api.db {
create table OkxPositionItemModel
}!
return api
}
fn (mut api Api) get_account_balance() ![]AccountBalance {
uri := '/api/v5/account/balance'
return api.request[Response[[]AccountBalance]](uri, .get)!.data
}
fn (mut api Api) get_account_positions() ![]AccountPosition {
uri := '/api/v5/account/positions'
return api.request[Response[[]AccountPosition]](uri, .get)!.data
}
fn (mut api Api) request[T](path string, method http.Method, params ...map[string]string) !T {
url_ := '${api.domain}${path}'
mut request := http.new_request(method, url_, '')
mut headers := http.new_header()
if method == .post {
headers.add(.content_type, 'application/json')
headers.add(.accept, 'application/json')
}
if params.len > 0 {
request.data = json.encode(params[0])
}
request.header = headers
$if !windows {
proxy := os.getenv_opt('https_proxy') or { os.getenv('HTTPS_PROXY') }
if proxy.len > 0 {
request.proxy = http.new_http_proxy(proxy)!
}
}
resp := request.do()!
if resp.status() != .ok && resp.status() != .no_content {
err := json.decode(ErrMsg, resp.body) or {
ErrMsg{
msg: '${err}'
}
}
return error(err.msg)
}
return json.decode(T, resp.body)!
}
@['/api/account/positions'; get]
pub fn (mut api Api) api_account_position() vweb.Result {
mut postions := api.get_account_positions() or { return api.failed(err) }
for i, mut postion in postions {
postion.recid = postion.inst_id
if postion.mgn_ratio.f64() * 100 <= 300 {
postion.w2ui.style = 'background-color: #f3d6e3'
} else if postion.upl_ratio.f64() * 100 < -50 {
postion.w2ui.style = 'background-color: rgb(242, 250, 140)'
} else {
mut ratio := 0
if postion.lever.f64() >= 20 {
ratio = 50
} else if postion.lever.f64() >= 10 {
ratio = 30
} else if postion.lever.f64() >= 3 {
ratio = 20
}
if postion.upl_ratio.f64() * 100 > ratio {
postion.w2ui.style = 'background-color: #C2F5B4'
}
}
postions[i] = postion
}
request := api.query['request'] or { '{}' }
dto := json.decode(RequestDto, request) or { RequestDto{} }
postions.sort_with_compare(fn [dto] (a &AccountPosition, b &AccountPosition) int {
if dto.sort.len == 0 {
return 0
}
mut left := ''
mut right := ''
left, right = match dto.sort[0].field {
'uplRatio' {
a.upl_ratio, b.upl_ratio
}
'upl' {
a.upl, b.upl
}
else {
'', ''
}
}
if left == right {
return 0
}
if dto.sort[0].direction == 'desc' {
return if left < right { -1 } else { 1 }
} else {
return if left > right { -1 } else { 1 }
}
})
return api.json(postions)
}
@['/api/account/balance'; get]
pub fn (mut api Api) api_account_balance() vweb.Result {
data := api.get_account_balance() or { return api.failed(err) }
return api.json(data)
}
pub fn (mut api Api) failed(err IError) vweb.Result {
return api.json(ErrMsg{ message: err.msg(), status: 'error' })
}
fn (mut api Api) serve() {
vweb.run(&api, 8090)
}
fn main() {
key := os.getenv('OKX_API_KEY')
secret := os.getenv('OKX_API_SECRET')
passphrase := os.getenv('OKX_PASSPHRASE')
mut api := Api.new(key, secret, passphrase)!
api.serve()
}
struct Response[T] {
code string @[omitempty]
msg string @[omitempty]
data T @[omitempty]
}
struct AccountBalanceDetail {
avail_bal string @[json: 'availBal'; omitempty]
avail_eq string @[json: 'availEq'; omitempty]
cash_bal string @[json: 'cashBal'; omitempty]
ccy string @[omitempty]
cross_liab string @[json: 'crossLiab'; omitempty]
dis_eq string @[json: 'disEq'; omitempty]
eq string @[omitempty]
eq_usd string @[json: 'eqUsd'; omitempty]
fixed_bal string @[json: 'fixedBal'; omitempty]
frozen_bal string @[json: 'frozenBal'; omitempty]
interest string @[omitempty]
iso_eq string @[json: 'isoEq'; omitempty]
iso_liab string @[json: 'isoLiab'; omitempty]
iso_upl string @[json: 'isoUpl'; omitempty]
liab string @[omitempty]
max_loan string @[json: 'maxLoan'; omitempty]
mgn_ratio string @[json: 'mgnRatio'; omitempty]
notional_lever string @[json: 'notionalLever'; omitempty]
ord_frozen string @[json: 'ordFrozen'; omitempty]
twap string @[omitempty]
u_time string @[json: 'uTime'; omitempty]
upl string @[omitempty]
upl_liab string @[json: 'uplLiab'; omitempty]
stgy_eq string @[json: 'stgyEq'; omitempty]
spot_in_use_amt string @[json: 'spotInUseAmt'; omitempty]
borrow_froz string @[json: 'borrowFroz'; omitempty]
spot_iso_bal string @[json: 'spotIsoBal'; omitempty]
}
struct AccountBalance {
adj_eq string @[json: 'adjEq'; omitempty]
borrow_froz string @[json: 'borrowFroz'; omitempty]
details []AccountBalanceDetail @[omitempty]
imr string @[omitempty]
iso_eq string @[json: 'isoEq'; omitempty]
mgn_ratio string @[json: 'mgnRatio'; omitempty]
mmr string @[omitempty]
notional_usd string @[json: 'notionalUsd'; omitempty]
ord_froz string @[json: 'ordFroz'; omitempty]
total_eq string @[json: 'totalEq'; omitempty]
u_time string @[json: 'uTime'; omitempty]
}
struct ErrMsg {
msg string @[omitempty]
message string @[omitempty]
status string @[omitempty]
}
struct W2ui {
pub mut:
style string
class string
summary bool
event string
}
struct AccountPosition {
adl string @[omitempty]
avail_pos string @[json: 'availPos'; omitempty]
avg_px string @[json: 'avgPx'; omitempty]
c_time string @[json: 'cTime'; omitempty]
ccy string @[omitempty]
delta_b_s string @[json: 'deltaBS'; omitempty]
delta_p_a string @[json: 'deltaPA'; omitempty]
gamma_b_s string @[json: 'gammaBS'; omitempty]
gamma_p_a string @[json: 'gammaPA'; omitempty]
imr string @[omitempty]
inst_id string @[json: 'instId'; omitempty]
inst_type string @[json: 'instType'; omitempty]
interest string @[omitempty]
idx_px string @[json: 'idxPx'; omitempty]
last string @[omitempty]
usd_px string @[json: 'usdPx'; omitempty]
be_px string @[json: 'bePx'; omitempty]
lever string @[omitempty]
liab string @[omitempty]
liab_ccy string @[json: 'liabCcy'; omitempty]
liq_px string @[json: 'liqPx'; omitempty]
mark_px string @[json: 'markPx'; omitempty]
margin string @[omitempty]
mgn_mode string @[json: 'mgnMode'; omitempty]
mgn_ratio string @[json: 'mgnRatio'; omitempty]
mmr string @[omitempty]
notional_usd string @[json: 'notionalUsd'; omitempty]
opt_val string @[json: 'optVal'; omitempty]
p_time string @[json: 'pTime'; omitempty]
pos string @[omitempty]
pos_ccy string @[json: 'posCcy'; omitempty]
pos_id string @[json: 'posId'; omitempty]
pos_side string @[json: 'posSide'; omitempty]
spot_in_use_amt string @[json: 'spotInUseAmt'; omitempty]
spot_in_use_ccy string @[json: 'spotInUseCcy'; omitempty]
theta_b_s string @[json: 'thetaBS'; omitempty]
theta_p_a string @[json: 'thetaPA'; omitempty]
trade_id string @[json: 'tradeId'; omitempty]
biz_ref_id string @[json: 'bizRefId'; omitempty]
biz_ref_type string @[json: 'bizRefType'; omitempty]
quote_bal string @[json: 'quoteBal'; omitempty]
base_bal string @[json: 'baseBal'; omitempty]
base_borrowed string @[json: 'baseBorrowed'; omitempty]
base_interest string @[json: 'baseInterest'; omitempty]
quote_borrowed string @[json: 'quoteBorrowed'; omitempty]
quote_interest string @[json: 'quoteInterest'; omitempty]
u_time string @[json: 'uTime'; omitempty]
upl string @[omitempty]
upl_last_px string @[json: 'uplLastPx'; omitempty]
upl_ratio string @[json: 'uplRatio'; omitempty]
upl_ratio_last_px string @[json: 'uplRatioLastPx'; omitempty]
vega_b_s string @[json: 'vegaBS'; omitempty]
vega_p_a string @[json: 'vegaPA'; omitempty]
realized_pnl string @[json: 'realizedPnl'; omitempty]
pnl string @[omitempty]
fee string @[omitempty]
funding_fee string @[json: 'fundingFee'; omitempty]
liq_penalty string @[json: 'liqPenalty'; omitempty]
pub mut:
w2ui W2ui @[json: 'w2ui'; omitempty]
recid string @[omitempty]
}
struct RequestDto {
pub mut:
limit i64
offset i64
sort []struct {
field string
direction string
}
}
PS C:\Users\Administrator\Desktop\xiusin-zig-examples> v run .\main_bad.v
main_bad.v:148:9: error: undefined ident: `api`
146 | })
147 |
148 | return api.json(postions)
| ~~~
149 | }
150 |
main_bad.v:148:13: error: cannot call a method using an invalid expression
146 | })
147 |
148 | return api.json(postions)
| ~~~~~~~~~~~~~~
149 | }
150 |
main_bad.v:148:2: error: `api.json(postions)` used as value
146 | })
147 |
148 | return api.json(postions)
| ~~~~~~~~~~~~~~~~~~~~~~~~~
149 | }
150 |
struct RequestDto {
pub mut:
limit i64
offset i64
sort []struct { // <----- the field name: sort
field string
direction string
}
}
The struct's field name 'sort' causes problems, so you can temporarily change the name to compile.
Whether sort can be used as a field name needs to be discussed, but I think it should be allowed and fixed.
Thank you for your feedback.
Describe the bug
Reproduction Steps
--
Expected Behavior
success compile
Current Behavior
failed
Possible Solution
No response
Additional Information/Context
No response
V version
V 0.4.3 e2334d8
Environment details (OS name and version, etc.)