How can I create an iterator of &T from either a &Vec<T> or Vec<&T>?

You can't just use the std::slice::Iter type for this.

If you don't want to copy the strings or vector, you'll have to implement your own iterator, for example:

struct FooIter<'a, 'b> {
    idx: usize,
    foo: &'b Foo<'a>,
}

impl<'a, 'b> Iterator for FooIter<'a, 'b> {
    type Item = &'a String;
    fn next(&mut self) -> Option<Self::Item> {
        self.idx += 1;
        match self.foo {
            Foo::Owned(v) => v.get(self.idx - 1),
            Foo::Refs(v) => v.get(self.idx - 1).map(|s| *s),
        }
    }
}

impl<'a, 'b> Foo<'a> {
    fn get_items(&'b self) -> FooIter<'a, 'b> {
        FooIter { idx: 0, foo: self }
    }
}

fn main() {
    let test: Vec<String> = vec!["a".to_owned(), "b".to_owned()];
    let foo = Foo::Owned(&test);
    for item in foo.get_items() {
        println!("{:?}", item);
    }
    let a = "a".to_string();
    let b = "b".to_string();
    let test: Vec<&String> = vec![&a, &b];
    let foo = Foo::Refs(test);
    for item in foo.get_items() {
        println!("{:?}", item);
    }
}

There is a handy crate, auto_enums, which can generate a type for you so a function can have multiple return types, as long as they implement the same trait. It's similar to the code in Denys Séguret's answer except it's all done for you by the auto_enum macro:

use auto_enums::auto_enum;

impl<'a> Foo<'a> {
    #[auto_enum(Iterator)]
    fn get_items(&self) -> impl Iterator<Item = &String> {
        match self {
            Foo::Owned(v) => v.iter(),
            Foo::Refs(v) => v.iter().copied(),
        }
    }
}

Add the dependency by adding this in your Cargo.toml:

[dependencies]
auto_enums = "0.6.3"

If you don't want to implement your own iterator, you need dynamic dispatch for this, because you want to return different iterators depending on the enum variant.

We need a trait object (&dyn Trait, &mut dyn Trait or Box<dyn Trait>) to use dynamic dispatch:

impl<'a> Foo<'a> {
    fn get_items(&'a self) -> Box<dyn Iterator<Item = &String> + 'a> {
        match self {
            Foo::Owned(v) => Box::new(v.into_iter()),
            Foo::Refs(v) => Box::new(v.iter().copied()),
        }
    }
}

.copied() converts the Iterator<Item = &&String> into an Iterator<Item = &String>, so this doesn't actually copy anything :)