4 ms·
If you want to do something like this, I'd highly recommend using a package like rs-bindata[0] (Rust) or go-bindata[1] (Go) to essentially embed the static data
by samhw 4y ago
If you want to do something like this, I'd highly recommend using a package like rs-bindata[0] (Rust) or go-bindata[1] (Go) to essentially embed the static data into your .data section automatically, rather than having to paste it into constants. (Of course, writing it out manually in source code will do the very same - and that's all these packages do, albeit in the preprocessing phase - but this way is less clunky, and I suspect likely more performant and footgun-free than your own implementation is likely to be.)
It's possible that you could even use this to enumerate all the files in some directory, such that you wouldn't require source code changes in order to add a new post - you'd simply need to run the preprocessor again in a different build environment.
Also, in the spirit of the post: it should be relatively easy to implement this oneself with a build script in Rust. In Go I don't think it's as easy, and iirc the author of the package uses the semi-public 'build tags' API[2] (which always gave me a sense of being grudgingly released, in one of the countless "we core developers mustn't allow the unwashed hordes of lowly application developers to have these dangerous, powerful tools" fights that seem to characterise Go development).
[0] https://github.com/glassbearInc/rs-bindata https://github.com/glassbearInc/rs-bindata
[1] https://github.com/jteeuwen/go-bindata https://github.com/jteeuwen/go-bindata
[2] https://pkg.go.dev/go/build#hdr-Build_Constraints https://pkg.go.dev/go/build#hdr-Build_Constraints
- nicoburns 4y agoIn Rust you can just use the built in `include_str!()` or `include_bytes!()` macros. let content: &'static str = include_str!("path/to/file");
- scottlamb 4y agoThe bindata package that samhw linked goes further by walking a whole directory and embedding it all, supplying a function that maps from pathname to file contents. Looks like it returns an Option<Vec<u8>> though [1] which means it must be copying the file contents each time. I don't know why they didn't just return a &'static [u8] instead. There's another crate includedir which looks more popular. It also supports compression. But if the file is stored in compressed form, looks like it also will (decompress/)copy into a fresh Vec, whether you request the uncompressed or compressed forms. [2] That's not what I would like. I'd prefer (lazily or eagerly) decompressing once and keeping it around in RAM for next time. YMMV. I could use a high-quality implementation of this same idea. Personally I don't get using it for a personal blog (I'd rather be able to change the content without recompiling/restarting), but on my todo list is producing a zero-dependency, single-binary form of software I'm working on, including its web interface. I might end up writing my own. [1] https://github.com/glassbearInc/rs-bindata/blob/93f61807b206d246aa920a5c0edf6317e11ebf04/rs-bindata-impl/src/lib.rs#L163 https://github.com/glassbearInc/rs-bindata/blob/93f61807b206... [2] lines 59 and 80, respectively. https://github.com/tilpner/includedir/blob/6a81c906e233649af1acec9835fe0a034b9274e2/lib/src/lib.rs#L59 https://github.com/tilpner/includedir/blob/6a81c906e233649af...
- samhw 4y agoOh nice, thank you! I’d like to pretend that I intentionally linked the crate for the reasons the other person gave, but to be perfectly honest I wasn’t aware of that. Much appreciated!
- jsolson 4y agoWhy not just use https://pkg.go.dev/embed https://pkg.go.dev/embed ?
- jerf 4y agoEmbed is fairly new; not new this release, but not that old. If you're not keeping up with every new release it is easy to not yet be aware of the new features. But, yes, to samhw's issues, it is now trivial in Go and built into the standard library to embed arbitrary files and/or directories into a Go executable. Also have no idea what the "semi-grudging" comment about build tags are; they've been there since the beginning and heavily used by the Go standard library for many things. Go, of all languages lately, is the most comfortable with reserving things for the compiler/runtime; if they wanted to, they would have. It was always obvious that build tags were necessary and I don't see what's "grudging" about them at all.
- samhw 4y agoYeah, this is the right answer in my case. I wrote Go professionally for a few years, a few years ago, and I haven’t really touched it since. All my knowledge will definitely be a few years out of date.
- mhio 4y agoI was able to do this in recent Go with stdlib embed - https://pkg.go.dev/embed https://pkg.go.dev/embed //go:embed player.html var player_html []byte
- veonik 4y agonice to see that in the stdlib! I don't see any mention of compression, I assume that can just be handled by something like upx, right?
- lifthrasiir 4y agoUPX would decompress the entire executable at once, which might or might not be okay for your use case.