I have a type
Span, which represents a region in a file, and is supposed to hold some data about that region: its location, the file where it belongs, the actual content of that region, maybe even the content of the neighbor lines, ... Since I want to build a lot of these spans, since a lot of them will most likely have overlapping data, and since they never need to modify the data they hold, just to read from it, it makes sense to share the content of a file among all the
Spans that are created while reading it. The problem is that there is no clear owner of that data: the function that reads the file and produces all the
Spans can only own that data for so long; no
Span should own data, since it isn't be clear which one should own it; there is no global state where I can just put all the data in and pass it around.
For this particular situation, it seemed to me that the most appropriate choice was an
Rc, since that's exactly what it provides: readonly shareable data with no clear owner. So for instance I have some fields with
Of course, when I create errors, I happily include the span of the concerned objects (that's why I keep them around, to produce nice error messages) in the error, and so far there is no problem.
The problem arises when I write some driver code for my library, and I try to use
Send + Sync, which rules out my error type, and so makes
I could turn my
Arc, but that strikes me as very wasteful: most of the
Spans I will create will not be included in an error, and yet each of them have to pay the overhead of
I could also "take ownership" in the error, that is, in the error, instead of having a
Span, I could have something like an
OwnedSpan which would just turn all the
String and all the
PathBuf, because one might argue that errors should be self-sufficient. And yet, I'm not convinced by this solution, among other things because that would require almost duplicating the code for
Span. Then I thought that maybe I need a trait
Spannable or something like that to avoid code duplication, but it looks like I'm missing the easy solution and that I'm trying to build something overly complicated.
On final other solution that was proposed to me was to use a
Cow<str>, but I don't think it fits this problem. At least, in my mental model of how
Cow works, it wouldn't be able to share pieces of a string.
So the question is: what is the proper way to deal with
anyhow? Can I, in some way, make it relax its
Send + Sync condition, that is completely useless for me (I have no threading, no asynchronous code, nothing alike). Is there another smart pointer that could solve this problem?