-
Notifications
You must be signed in to change notification settings - Fork 56
attributed_text: switch to structured Error + ErrorKind with bo…
#458
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
attributed_text: switch to structured Error + ErrorKind with bo…
#458
Conversation
…undary details
- Replace `ApplyAttributeError` with `Error { kind: ErrorKind, start, end, len, boundary }`
- `AttributedText::apply_attribute` now returns Result<(), Error>
- Add `Endpoint` and `BoundaryInfo` (reports offending endpoint/index and enclosing codepoint span)
- Enforce UTF-8 boundaries via `TextStorage::is_char_boundary` and surface detailed context
- Enrich `Display` to include range, len, and boundary info
- Re-export `Error`, `ErrorKind`, `BoundaryInfo`, `Endpoint` at crate root
- Update tests to assert kinds and key details in messages
49fb329 to
aeadccd
Compare
tomcur
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good. Some nits inline, and perhaps the testing of the Display implementation in bad_range_for_apply_attribute should be snapshot-y, testing against the full output string we expect. Anyway, I've left some comments about the current asserts.
| if s == 0 { | ||
| break; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In principle this should be impossible, as text.is_char_boundary(0) should always be true.
| if s == 0 { | |
| break; | |
| } | |
| // We can never wrap around `0` here, as when `s == 0` before the decrement, | |
| // the previous call to `text.is_char_boundary` (either in this loop or above) | |
| // will have returned `true`. | |
| debug_assert!(s != 0, "`s` should never wrap around 0"). |
| assert_eq!(e.kind(), ErrorKind::InvalidRange); | ||
| let msg = format!("{}", e); | ||
| assert!(msg.contains("4..3")); | ||
| assert!(msg.contains("start > end") || msg.contains("invalid range")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we expect to always keep saying both that the range is invalid, and why it's invalid?
| assert!(msg.contains("start > end") || msg.contains("invalid range")); | |
| assert!(msg.contains("start > end")); | |
| assert!(msg.contains("invalid range")); |
| Err(e) => { | ||
| assert_eq!(e.kind(), ErrorKind::InvalidBounds); | ||
| let msg = format!("{}", e); | ||
| assert!(msg.contains("7..8") || msg.contains("8")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to above, this perhaps should be &&, but at the same time, as written the second expression is implied by the first.
…undary details
ApplyAttributeErrorwithError { kind: ErrorKind, start, end, len, boundary }AttributedText::apply_attributenow returns Result<(), Error>EndpointandBoundaryInfo(reports offending endpoint/index and enclosing codepoint span)TextStorage::is_char_boundaryand surface detailed contextDisplayto include range, len, and boundary infoError,ErrorKind,BoundaryInfo,Endpointat crate root