Skip to content

Commit 1e912e9

Browse files
committed
Make PathAttributes.raw T: AsRef<[u8]> again
1 parent e7baeb4 commit 1e912e9

File tree

1 file changed

+58
-59
lines changed

1 file changed

+58
-59
lines changed

src/bgp/path_attributes_ng.rs

+58-59
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,9 @@ pub struct MpReachNlri<T: AsRef<[u8]>> {
137137
}
138138

139139

140-
#[derive(Clone, PartialEq)]
141-
pub struct PathAttributes<'pa, 'sc, ASL>{
140+
#[derive(Clone, Debug, PartialEq)]
141+
//pub struct PathAttributes<'pa, 'sc, ASL, T: 'pa + AsRef<[u8]>>{
142+
pub struct PathAttributes<'sc, ASL, T: AsRef<[u8]>>{
142143
asl: std::marker::PhantomData::<ASL>,
143144
// XXX perhaps session_config should not live here
144145
// - 'stand alone path attributes' (i.e., stored in the store or on disk)
@@ -149,16 +150,16 @@ pub struct PathAttributes<'pa, 'sc, ASL>{
149150
// - if we really want a stand alone owned version of things, a classic
150151
// PduParseInfo (Copy) should suffice
151152
session_config: Cow<'sc, SessionConfig>,
152-
raw: Cow<'pa, [u8]>,
153-
}
154-
impl<'pa, 'sc, ASL> std::fmt::Debug for PathAttributes<'pa, 'sc, ASL> {
155-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
156-
match self.raw {
157-
Cow::Borrowed(_) => f.write_str("borrowed"),
158-
Cow::Owned(_) => f.write_str("owned"),
159-
}
160-
}
153+
raw: T,
161154
}
155+
//impl<'sc, ASL, T: AsRef<[u8]>> std::fmt::Debug for PathAttributes<'sc, ASL, T> {
156+
// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
157+
// match self.raw {
158+
// Cow::Borrowed(_) => f.write_str("borrowed"),
159+
// Cow::Owned(_) => f.write_str("owned"),
160+
// }
161+
// }
162+
//}
162163

163164
/// Overlay/cache over immutable PathAttributes
164165
///
@@ -171,8 +172,8 @@ impl<'pa, 'sc, ASL> std::fmt::Debug for PathAttributes<'pa, 'sc, ASL> {
171172
/// XXX: Option<Range<usize>> vs Option<RawAttribute> vs Option<ProperType> ?
172173
/// Perhaps this thing can double as a builder if we go Option<Cow<_>> ?
173174
#[derive(Debug)]
174-
pub struct PathAttributesOverlay<'pa, 'sc, ASL> {
175-
path_attributes: &'pa PathAttributes<'pa, 'sc, ASL>,
175+
pub struct PathAttributesOverlay<'pa, 'sc, ASL, T: AsRef<[u8]>> {
176+
path_attributes: &'pa PathAttributes<'sc, ASL, T>,
176177
updated: bool,
177178
origin: Option<Cow<'pa, [u8]>>,
178179
communities: Option<Cow<'pa, [u8]>>,
@@ -181,8 +182,8 @@ pub struct PathAttributesOverlay<'pa, 'sc, ASL> {
181182
//...
182183
//...
183184
}
184-
impl<'pa, 'sc: 'pa, ASL: 'pa> PathAttributesOverlay<'pa, 'sc, ASL> {
185-
pub fn for_unchecked(path_attributes: &'pa PathAttributes<'pa, 'sc, ASL>) -> Self {
185+
impl<'pa, 'sc: 'pa, ASL: 'pa, T: AsRef<[u8]>> PathAttributesOverlay<'pa, 'sc, ASL, T> {
186+
pub fn for_unchecked(path_attributes: &'pa PathAttributes<'sc, ASL, T>) -> Self {
186187
let mut origin = None;
187188
let mut communities = None;
188189
for raw in path_attributes.iter() {
@@ -243,7 +244,7 @@ impl<'pa, 'sc: 'pa, ASL: 'pa> PathAttributesOverlay<'pa, 'sc, ASL> {
243244
}
244245
}
245246

246-
pub fn owned(&self) -> PathAttributes<'pa, 'sc, ASL> {
247+
pub fn owned(&self) -> PathAttributes<'sc, ASL, Vec<u8>> {
247248
self.path_attributes.owned()
248249
}
249250
}
@@ -266,10 +267,10 @@ impl<'pa, 'sc: 'pa, ASL: 'pa> PathAttributesOverlay<'pa, 'sc, ASL> {
266267
// XXX here, we lack compile time checks of whether all fields in the overlay
267268
// are actually checked and written to the returned Vec.
268269
// declarative macros are not going to save us, I suppose.
269-
impl<'pa, 'sc, ASL> From<&PathAttributesOverlay<'pa, 'sc, ASL>> for Vec<u8> {
270-
fn from(pao: &PathAttributesOverlay<'pa, 'sc, ASL>) -> Self {
270+
impl<'pa, 'sc, ASL, T: AsRef<[u8]>> From<&PathAttributesOverlay<'pa, 'sc, ASL, T>> for Vec<u8> {
271+
fn from(pao: &PathAttributesOverlay<'pa, 'sc, ASL, T>) -> Self {
271272
if !pao.updated {
272-
return pao.path_attributes.raw.to_vec();
273+
return pao.path_attributes.raw.as_ref().to_vec();
273274
}
274275
let mut res = Vec::new();
275276
if let Some(raw) = pao.origin.as_ref() {
@@ -285,65 +286,63 @@ impl<'pa, 'sc, ASL> From<&PathAttributesOverlay<'pa, 'sc, ASL>> for Vec<u8> {
285286
}
286287
}
287288

288-
impl<'pa, 'sc, ASL> From<PathAttributesOverlay<'pa, 'sc, ASL>> for Vec<u8> {
289-
fn from(pao: PathAttributesOverlay<'pa, 'sc, ASL>) -> Self {
289+
impl<'pa, 'sc, ASL, T: AsRef<[u8]>> From<PathAttributesOverlay<'pa, 'sc, ASL, T>> for Vec<u8> {
290+
fn from(pao: PathAttributesOverlay<'pa, 'sc, ASL, T>) -> Self {
290291
(&pao).into()
291292
}
292293
}
293294

294295

295296

296-
impl<'pa, 'sc, ASL> PathAttributes<'pa, 'sc, ASL> {
297-
pub fn owned(&self) -> PathAttributes<'pa, 'sc, ASL> {
297+
impl<'sc, ASL, T: AsRef<[u8]>> PathAttributes<'sc, ASL, T> {
298+
pub fn owned(&self) -> PathAttributes<'sc, ASL, Vec<u8>> {
298299
PathAttributes {
299300
asl: std::marker::PhantomData::<ASL>,
300301
session_config: self.session_config.clone(),
301-
raw: self.raw.clone(),
302+
raw: self.raw.as_ref().to_vec()
302303
}
303304
}
304305
}
305306

306-
impl<'pa, 'sc, ASL> From<&PathAttributes<'pa, 'sc, ASL >> for Vec<u8> {
307-
fn from(pas: &PathAttributes<'pa, 'sc, ASL>) -> Self {
308-
pas.raw.to_vec()
307+
impl<'pa, 'sc, ASL, T: AsRef<[u8]>> From<&PathAttributes<'sc, ASL, T>> for Vec<u8> {
308+
fn from(pas: &PathAttributes<'sc, ASL, T>) -> Self {
309+
pas.raw.as_ref().to_vec()
309310
}
310311
}
311-
impl<'pa, 'sc, ASL> From<PathAttributes<'pa, 'sc, ASL>> for Vec<u8> {
312-
fn from(pas: PathAttributes<'pa, 'sc, ASL>) -> Self {
313-
pas.raw.to_vec()
312+
impl<'sc, ASL, T: AsRef<[u8]>> From<PathAttributes<'sc, ASL, T>> for Vec<u8> {
313+
fn from(pas: PathAttributes<'sc, ASL, T>) -> Self {
314+
pas.raw.as_ref().to_vec()
314315
}
315316
}
316-
impl<'pa, 'sc, ASL> From<Vec<u8>> for PathAttributes<'pa, 'sc, ASL> {
317+
impl<'sc, ASL> From<Vec<u8>> for PathAttributes<'sc, ASL, Vec<u8>> {
317318
fn from(raw: Vec<u8>) -> Self {
318319
PathAttributes {
319320
asl: std::marker::PhantomData::<ASL>,
320321
session_config: Cow::Owned(SessionConfig::modern()),
321-
raw: Cow::Owned(raw),
322+
raw,
322323
}
323324
}
324325
}
325326

326-
impl<'pa, 'sc> PathAttributes<'pa, 'sc, FourByteAsns> {
327-
327+
impl<'pa, 'sc> PathAttributes<'sc, FourByteAsns, Vec<u8>> {
328328
pub fn modern() -> Self {
329329
PathAttributes {
330330
asl: std::marker::PhantomData::<FourByteAsns>,
331331
session_config: Cow::Owned(SessionConfig::modern()),
332-
raw: Cow::Owned(Vec::new())
332+
raw: Vec::new()
333333
}
334334
}
335335
}
336336

337-
impl<'pa, 'sc, ASL> PathAttributes<'pa, 'sc, ASL> {
338-
337+
impl<'sc, ASL> PathAttributes<'sc, ASL, Vec<u8>> {
339338
pub fn append_unchecked<PA: ToWireformat>(&mut self, pa: PA) {
340-
pa.write(self.raw.to_mut());
339+
pa.write(&mut self.raw);
341340
}
342341
}
343342

344343

345-
pub struct PathAttributesIter<'pa, 'sc, ASL> {
346-
raw_attributes: &'pa PathAttributes<'pa, 'sc, ASL>,
344+
pub struct PathAttributesIter<'pa, 'sc, ASL, T: AsRef<[u8]>> {
345+
raw_attributes: &'pa PathAttributes<'sc, ASL, T>,
347346
idx: usize,
348347
}
349348

@@ -391,7 +390,7 @@ impl<'a> RawAttribute<&'a [u8]> {
391390
}
392391
}
393392

394-
impl<'pa, 'sc, ASL> Iterator for PathAttributesIter<'pa, 'sc, ASL> {
393+
impl<'pa, 'sc, ASL, T: AsRef<[u8]>> Iterator for PathAttributesIter<'pa, 'sc, ASL, T> {
395394
type Item = RawAttribute<&'pa [u8]>;
396395
fn next(&mut self) -> Option<Self::Item> {
397396
if self.idx == self.raw_attributes.raw.as_ref().len() {
@@ -420,18 +419,18 @@ impl<'pa, 'sc, ASL> Iterator for PathAttributesIter<'pa, 'sc, ASL> {
420419
}
421420
}
422421

423-
impl<'pa, 'sc> PathAttributes<'pa, 'sc, FourByteAsns> {
424-
pub fn new(raw: impl Into<Cow<'pa, [u8]>> , session_config: &'sc SessionConfig) -> Self {
422+
impl<'pa, 'sc, T: AsRef<[u8]>> PathAttributes<'sc, FourByteAsns, T> {
423+
pub fn new(raw: T, session_config: &'sc SessionConfig) -> Self {
425424
Self {
426425
asl: std::marker::PhantomData,
427426
session_config: Cow::Borrowed(session_config),
428-
raw: raw.into()
427+
raw,
429428
}
430429

431430
}
432431
}
433-
impl<'pa, 'sc> PathAttributes<'pa, 'sc, TwoByteAsns> {
434-
pub fn legacy(raw: impl Into<Cow<'pa, [u8]>>, session_config: &'sc SessionConfig) -> Self {
432+
impl<'sc, T: AsRef<[u8]>> PathAttributes<'sc, TwoByteAsns, T> {
433+
pub fn legacy(raw: T, session_config: &'sc SessionConfig) -> Self {
435434
Self {
436435
asl: std::marker::PhantomData,
437436
session_config: Cow::Borrowed(session_config),
@@ -441,8 +440,8 @@ impl<'pa, 'sc> PathAttributes<'pa, 'sc, TwoByteAsns> {
441440
}
442441
}
443442

444-
impl<'pa, 'sc, ASL> PathAttributes<'pa, 'sc, ASL> {
445-
pub fn iter(&self) -> PathAttributesIter<ASL> {
443+
impl<'pa, 'sc, ASL, T: AsRef<[u8]>> PathAttributes<'sc, ASL, T> {
444+
pub fn iter(&self) -> PathAttributesIter<ASL, T> {
446445
PathAttributesIter {
447446
raw_attributes: self,
448447
idx: 0
@@ -458,7 +457,7 @@ impl<'pa, 'sc, ASL> PathAttributes<'pa, 'sc, ASL> {
458457
// Not sure whether that's actually worth it...
459458
//
460459
// And ideally, we can specify an order, e.g. by typecode.
461-
pub fn pure_mp_attributes(&self) -> Option<PathAttributes<'pa, 'sc, ASL>> {
460+
pub fn pure_mp_attributes(&self) -> Option<PathAttributes<'sc, ASL, Vec<u8>>> {
462461
self.get_by_type_code(MpReachNlri::TYPECODE)?;
463462

464463
let mut res = Vec::with_capacity(self.raw.as_ref().len());
@@ -471,20 +470,20 @@ impl<'pa, 'sc, ASL> PathAttributes<'pa, 'sc, ASL> {
471470
Some(PathAttributes {
472471
asl: std::marker::PhantomData,
473472
session_config: self.session_config.clone(),
474-
raw: res.into()
473+
raw: res,
475474
})
476475
}
477476
}
478477

479-
impl<'pa, 'sc> PathAttributes<'pa, 'sc, FourByteAsns> {
478+
impl<'pa, 'sc, T: AsRef<[u8]>> PathAttributes<'sc, FourByteAsns, T> {
480479
pub fn get_aspath(&'pa self) -> Option<AsPath<FourByteAsns, &'pa [u8]>> {
481480
self.get_by_type_code(PathAttributeType::AsPath).and_then(|raw|
482481
AsPath::<FourByteAsns, &[u8]>::try_from_raw(raw).ok()
483482
)
484483
}
485484
}
486485

487-
impl<'pa, 'sc, ASL> PathAttributes<'pa, 'sc, ASL> {
486+
impl<'pa, 'sc, ASL, T: AsRef<[u8]>> PathAttributes<'sc, ASL, T> {
488487
/// Returns `Some(PA)` if it exists and is valid, otherwise returns None.
489488
pub fn get_lossy<PA: 'pa + Wireformat<'pa> + TryFromRaw<'pa>>(&'pa self) -> Option<PA> {
490489
self.get_by_type_code(PA::TYPECODE).and_then(|raw|
@@ -501,13 +500,13 @@ impl<'pa, 'sc, ASL> PathAttributes<'pa, 'sc, ASL> {
501500

502501
//------------ Test with fake Update msg --------------------------------------
503502

504-
struct UpdateMsg<'pa, 'sc, ASL> {
505-
path_attributes: PathAttributes<'pa, 'sc, ASL>,
503+
struct UpdateMsg<'sc, ASL, T: AsRef<[u8]>> {
504+
path_attributes: PathAttributes<'sc, ASL, T>,
506505
session_config: &'sc SessionConfig,
507506
}
508507

509-
impl <'pa, 'sc, ASL> UpdateMsg<'pa, 'sc, ASL> {
510-
pub fn path_attributes(&self) -> &PathAttributes<'pa, 'sc, ASL> {
508+
impl <'sc, ASL, T: AsRef<[u8]>> UpdateMsg<'sc, ASL, T> {
509+
pub fn path_attributes(&self) -> &PathAttributes<'sc, ASL, T> {
511510
&self.path_attributes
512511
}
513512

@@ -535,7 +534,7 @@ macro_rules! validate_match {
535534

536535
macro_rules! validate_for_asl {
537536
($asl:ident) => {
538-
impl<'pa, 'sc> PathAttributes<'pa, 'sc, $asl> {
537+
impl<'sc, T: AsRef<[u8]>> PathAttributes<'sc, $asl, T> {
539538
pub fn validate(&self, level: ValidationLevel) -> bool {
540539
use PathAttributeType as PAT;
541540
self.iter().all(|raw|{
@@ -1016,7 +1015,7 @@ mod tests {
10161015

10171016
let raw = Vec::<u8>::from(pas.clone());
10181017

1019-
let pas_again = PathAttributes::<FourByteAsns>::from(raw);
1018+
let pas_again = PathAttributes::<FourByteAsns, _>::from(raw);
10201019
assert_eq!(pas.owned(), pas_again.owned());
10211020

10221021
}
@@ -1028,7 +1027,7 @@ mod tests {
10281027
pas.append_unchecked(OwnedCommunities(vec![Community(10), Community(11)]));
10291028
let raw = Vec::<u8>::from(pas.clone());
10301029
// TODO impl From<&pas> for Vec<u8>> let raw = Vec::<u8>::from(&pas);
1031-
let pas2 = PathAttributes::<FourByteAsns>::from(raw);
1030+
let pas2 = PathAttributes::<FourByteAsns, _>::from(raw);
10321031
let mut overlay = PathAttributesOverlay::for_unchecked(&pas2);
10331032

10341033
// Everything is the same

0 commit comments

Comments
 (0)