ChanServ changed the topic of #crystal-lang to: The Crystal programming language | https://crystal-lang.org | Fund Crystal's development: https://crystal-lang.org/sponsors | GH: https://github.com/crystal-lang/crystal | Docs: https://crystal-lang.org/docs | Gitter: https://gitter.im/crystal-lang/crystal
lanodan has quit [Quit: WeeChat 3.4.1]
lanodan has joined #crystal-lang
notzmv has joined #crystal-lang
jmd_ has quit [Ping timeout: 260 seconds]
ur5us_ has joined #crystal-lang
nq has quit [Quit: Leaving]
vegai has joined #crystal-lang
<vegai> hey, I thought about trying the interpreter on 1.4.0
<vegai> what would be the cleanest way to get the linking work when installing to /usr/local ?
<vegai> my librt is in /usr/lib, but seems like the search path doesn't include that
vegai has quit [Quit: to matrix]
<FromGitter> <vegai:kapsi.fi> oh wait, crystal is looking it from a wrong place anyway
<FromGitter> <vegai:kapsi.fi> cannot find -lrt (/usr/local/bin/../lib/crystal/librt.so: cannot open shared object file: No such file or directory)
<FromGitter> <vegai:kapsi.fi> well, two symlinks later (libdl.so also) and the interpreter works
ur5us_ has quit [Quit: Leaving]
ur5us has joined #crystal-lang
ur5us has quit [Ping timeout: 268 seconds]
jhass has quit [Ping timeout: 250 seconds]
straight-shoota has quit [Ping timeout: 272 seconds]
DeBot has quit [Ping timeout: 240 seconds]
DeBot_ has joined #crystal-lang
jhass has joined #crystal-lang
straight-shoota has joined #crystal-lang
<FromGitter> <moe:busyloop.net> is there a more efficient way to convert a `Hash` or `NamedTuple` to `JSON::Any` than serializing it to json and parsing it back? https://carc.in/#/r/d0o1
<FromGitter> <jrei:matrix.org> https://crystal-lang.org/api/master/JSON/Any.html#new%28raw%3AType%29-class-method
<FromGitter> <jrei:matrix.org> You'll have to iterate over and create a JSON::Any for the value
<FromGitter> <jrei:matrix.org> BTW Crystalizer does it out-of-the-box
<FromGitter> <moe:busyloop.net> hm hm
<FromGitter> <jrei:matrix.org> https://carc.in/#/r/d0o8
<FromGitter> <moe:busyloop.net> merci!
<FromGitter> <jrei:matrix.org> Hum no Crystalizer doesn't have it, but it can convert Anys to one another
<FromGitter> <jrei:matrix.org> All are the same base module, so
<FromGitter> <jrei:matrix.org> One can convert a JSON::Any to yaml and vice-versa at no additional cost
<FromGitter> <jrei:matrix.org> moe (https://matrix.to/#/@moe:busyloop.net): why do you need to do that though?
sorcus has quit [Quit: WeeChat 3.5]
<FromGitter> <moe:busyloop.net> just a helper class where the user should be able to pass in an arbitrary hash or chunk of json: `JsonApi::Error.new(status: 123, code: "foo", meta: { foo: "bar" } )` (some fields like status & code are fixed, but `meta` can take any json value)
<FromGitter> <moe:busyloop.net> i think your snippet might work, gonna try it out :)
<FromGitter> <jrei:matrix.org> It has to be enhanced, convertings integer and floats for instance
<FromGitter> <moe:busyloop.net> yeh, i've stashed it onto the "fix later" pile. for now json ser+deser works, it's just ugly
<FromGitter> <Blacksmoke16> Why do you need to convert it to json any first?
<FromGitter> <Blacksmoke16> To add the status and code fields?
<FromGitter> <moe:busyloop.net> cause i need to store it in an ivar on the other side, later to be json serialized
<FromGitter> <moe:busyloop.net> slightly simplified: https://carc.in/#/r/d0p3
<FromGitter> <moe:busyloop.net> could perhaps make it a generic in this case, but well, other fish to fry atm :D
<FromGitter> <jrei:matrix.org> Also keep in mind could want a XML or even GraphQL or GRPC API 😉
<FromGitter> <Blacksmoke16> could also just do like `@data = { status: status, code: code, meta: meta }.to_json` and call it a day :P
<FromGitter> <moe:busyloop.net> yeh, maybe for simpler cases. not for my 3 layers of macros here :P
<FromGitter> <Blacksmoke16> :S fair enough
<FromGitter> <moe:busyloop.net> @Blacksmoke16: https://carc.in/#/r/d0p4 😏
<FromGitter> <Blacksmoke16> isnt that just essentially the `record` macro?
<FromGitter> <Blacksmoke16> but for a class
<FromGitter> <moe:busyloop.net> close, yes. but this one takes a NamedTuple. which allows passing it around more easily. which i needed for my crazy DSL
<FromGitter> <moe:busyloop.net> it can do this now: https://carc.in/#/r/d0p8 - with auto-swagger docs, validation, content-negotiation etc.
<FromGitter> <Blacksmoke16> Pretty slick! I see you didn't switch your router yet tho 😛
<FromGitter> <jrei:matrix.org> I like it
<FromGitter> <moe:busyloop.net> haha. i actually looked at athena router, might still swap it out. just too many other things to still patch up, that comes last.
<FromGitter> <jrei:matrix.org> I don't know if you've done it, I find sleeker internally if exceptions are not used for 4xx/5xx responses
<FromGitter> <jrei:matrix.org> If find this not very good
<FromGitter> <Blacksmoke16> Haha sounds good 👍
<FromGitter> <jrei:matrix.org> What compile-time guarantees does your framework provides?
<FromGitter> <Blacksmoke16> Exceptions just work so good for error handling like that, I'd think not using them would make things much more complex
<FromGitter> <moe:busyloop.net> yup, responses incl. errors are pre-declared. but exceptions are also properly rendered (can declare are renderer for specific Exception classes, such as ORM errors - otherwise the standard Exception-renderer takes them). this should make it easy to deal with ORMs - no need to catch things like validation errors, just have a renderer for them.
<FromGitter> <moe:busyloop.net> i learned pre-declaring them is pretty much inevitable to generate those docs (as there's no way to discover return-types in crystal unless they are explicitly declared - i think i had asked about that in here the other day)
<FromGitter> <jrei:matrix.org> Exceptions are not compile-time safe, and cannot be automatically showed in swagger docs :/
<FromGitter> <jrei:matrix.org> If an endpoint use return types, like Success | Error, then the swagger docs generator can use this automatically
<FromGitter> <jrei:matrix.org> moe (https://matrix.to/#/@moe:busyloop.net): ha nice!
<FromGitter> <jrei:matrix.org> A bit like what's I did with my framework too
<FromGitter> <moe:busyloop.net> yap, that's totally right. the way i've solved it (for now) is that exception-renderers automatically add to the Swagger-docs for *all* endpoints. since they can in principle bubble up from anywhere. but not happy with that, yet. if there's a renderer for "Orm::Error" then i don't really want that in the docs for endpoints that don't even use the orm.
<FromGitter> <jrei:matrix.org> In case you'd like some ideas: https://github.com/grip-framework/gripen
<FromGitter> <moe:busyloop.net> guess i'll make a macro to opt-in/opt-out. basically hitting the limit of what can be discovered in crystal there (couldn't find a way to discover any info about exceptions in macro-space)
<FromGitter> <moe:busyloop.net> yea i've looked at that, really cool! :) i just could never figure out the status of grip vs gripen, and it seemed sadly not very maintained
<FromGitter> <jrei:matrix.org> There are separate
<FromGitter> <jrei:matrix.org> @grkek and me thought of having gripen as the grip v2. But at the end, lack of interest to most so didn't materialized
<FromGitter> <jrei:matrix.org> At the end you can see as an experiment. No issues, nothing to do haha 😆
<FromGitter> <jrei:matrix.org> Even Grip is not that used much 🤷
<FromGitter> <moe:busyloop.net> i did use it for a while! but then i keep derailing into building my own frameworks lol
<FromGitter> <moe:busyloop.net> i also started with icyleaf for swagger, but turned out too rigid for me, and also missed some stuff
<FromGitter> <moe:busyloop.net> so now i'm just using the amazing AnyHash and merge to it from all over the places: https://gist.github.com/m-o-e/74f7f64c26a743387bb6ef5e08c53ce5
<FromGitter> <Blacksmoke16> sure but isnt not using them much more complex just to get swagger docs?
<FromGitter> <Blacksmoke16> related: https://github.com/crystal-lang/crystal/issues/8353
<FromGitter> <Blacksmoke16> > guess i'll make a macro to opt-in/opt-out. basically hitting the limit of what can be discovered in crystal there (couldn't find a way to discover any info about exceptions in macro-space) ⏎ ⏎ related: https://github.com/crystal-lang/crystal/issues/8353
<FromGitter> <moe:busyloop.net> this gives me hope: https://github.com/crystal-lang/crystal/issues/8353#issuecomment-625765718
<FromGitter> <Blacksmoke16> if it goes the annotation route, could deff access that in a macro, not so much if its in a comment
<FromGitter> <moe:busyloop.net> yeh, i just want `Def.exceptions` without having to manually declare them (how am i supposed to know what can bubble up from inside the guts of stdlib, that would probably be a dozen lines on every method ;))
<FromGitter> <moe:busyloop.net> but it's probably more a crystal 3.0 type of thing
<FromGitter> <Blacksmoke16> indeed
<FromGitter> <Blacksmoke16> even if thats a thing, prob easier to manually do it anyway
<FromGitter> <Blacksmoke16> because, to your point, are prob going to be a lot of random ones that *could* happen, but in reality wont
jmdaemon has joined #crystal-lang
<FromGitter> <moe:busyloop.net> well, you'd only declare renderers for the ones you care about (like `Orm::ValidationError`). ⏎ then the framework would add their docs only to endpoints that actually raise them. ⏎ ⏎ the rest flows into `Exception` renderer (http 500). the docs for which also get added to all endpoints (because `Exception` can be raised from anywhere). [https://gitter.im/c
<FromGitter> ... rystal-lang/crystal?at=625326868db2b95f0aacf27e]
<FromGitter> <Blacksmoke16> ahh okay, yea that makes more sense
<FromGitter> <moe:busyloop.net> yeh, wishful thinking for now. but anyway, already quite happy with what i got so far. keeping the swagger those swagger comment-annotations in sync with what the handler actually does has been a pain point in pretty much every project here. having 99% of it fall out automatically will already make life easier.
<FromGitter> <Blacksmoke16> how are you handling validations?
taupiqueur has joined #crystal-lang
<FromGitter> <moe:busyloop.net> nothing too fancy, just have a param class for each type: https://gist.github.com/m-o-e/f0bc661afd4ec2de48e18ae8ef15a6c1
<FromGitter> <moe:busyloop.net> the args in `initialize` automatically become available in the macro, so each type can have different ones
<FromGitter> <Blacksmoke16> 👍 gotcha
f1refly has joined #crystal-lang
<FromGitter> <moe:busyloop.net> https://gist.github.com/m-o-e/c9c26aee89293b00ba4af235f8123c8f <- here's the fancy part of that. macro mania. ⏎ (renderer can be ignored, that's still from the early days. gotta change it to just re-raise as `JsonApi::Error` sometime - no need to duplicate the response-formatting in there)
brw has quit [Quit: The Lounge - https://thelounge.chat]
brw has joined #crystal-lang
* FromGitter * Blacksmoke16 wants his macro defs
<FromGitter> <moe:busyloop.net> can't spill all the beans yet :p
<FromGitter> <Blacksmoke16> dont forget about testing ^
<FromGitter> <Blacksmoke16> having some good ways provided by the framework to do that can be helpful
f1refly has quit [Read error: Connection reset by peer]
taupiqueur has quit [Quit: taupiqueur]
f1refly has joined #crystal-lang
ur5us has joined #crystal-lang
<FromGitter> <moe:busyloop.net> yup, my religion is end-to-end testing, so i got spec helpers to simulate requests and this little db doodad in spec_helper.cr https://carc.in/#/r/d0r8
<FromGitter> <Blacksmoke16> 👍 nice
<FromGitter> <Blacksmoke16> Tho i mean exposing those helpers to let users of the framework use them too
<FromGitter> <moe:busyloop.net> yea they can, i mean, it's all just in the spec_helper :D
<FromGitter> <moe:busyloop.net> https://carc.in/#/r/d0re
<FromGitter> <moe:busyloop.net> so just require lux/spec_helper and it'll be there. athena prob has something similar
<FromGitter> <moe:busyloop.net> admittedly mine has no fancy DI/mocking or anything like that. maybe later. tho tbh, i've never found that very useful in the past. ultimately i just wanna know that request A gives response B. what happens in between... well, if the response is correct, then it's probably correct ;)
<FromGitter> <Blacksmoke16> I never considered just requiring another libs spec helper
<FromGitter> <moe:busyloop.net> well, strictly speaking it's the spec_helper_helper ;)
<FromGitter> <Blacksmoke16> Always assumed that was a bad idea and exposed a dedicated spec.cr file
<FromGitter> <Blacksmoke16> Ahh gotcha
<FromGitter> <moe:busyloop.net> yea, it's probably not "clean" to inject top-level helpers like that. but it works and not sure what a cleaner way would really look like (or gain).
<FromGitter> <jrei:matrix.org> You could make it a module I guess
<FromGitter> <jrei:matrix.org> With `def self.mock_request`. Up to the user to include it where needed
<FromGitter> <jrei:matrix.org> Or call the method directly from the module
<FromGitter> <moe:busyloop.net> yea, but that's prob part of the things i learned while dabbling with this. ⏎ if you want to be truly dynamic then "clean" doesn't go far. it's macros and generating classes all the way. initially i tried very hard to enable "Lux.new" and having multiple instances in peaceful coexistence. but then realistically, who really need multiple server instances in their app... things became way easier after
<FromGitter> ... accepting it has to be a "there can be only one" kemal-style affair
<FromGitter> <moe:busyloop.net> so in the main app all the generated stuff is tucked away under the Lux namespace, to keep a bit of isolation at least. but in the spec-helper... i guess could namespace that as well. but if you require that then you're probably testing a lux app. so why type four extra letters instead of just get("/foo") 🤷‍♂️
<FromGitter> <moe:busyloop.net> the other thing i learned: basically every macro error is fixed by adding a backslash before {% :P
<FromGitter> <Blacksmoke16> could still do that by just having two separate entrypoints that require common code and only the routes each server should have
<FromGitter> <Blacksmoke16> do you know about `{{debug}}`?
<FromGitter> <moe:busyloop.net> ha, yea, it's fun to get these comments from other framework devs. :D of course you'd spot that right away and yea that's exactly my thinking. i can have multiple listeners already, will prob add optional scoping of endpoints to listeners sometime. so then multiple "instances" will be possible, just without it being an actual class instance.
<FromGitter> <moe:busyloop.net> yea {{debug}} is mighty helpful, although i've needed it surprisingly rarely. the compiler errors have gotten really good, most of the time it dumps the relevant part by itself
<FromGitter> <Blacksmoke16> exactly yea. Its mostly under the "worry about it when there's an actual use case for it" bucket
ur5us has quit [Ping timeout: 268 seconds]